Auth Email Rework (#1567)
* Hooked up Send to for Series and volumes and fixed a bug where Email Service errors weren't propagating to the UI layer. When performing actions on series detail, don't disable the button anymore. * Added send to action to volumes * Fixed a bug where .kavitaignore wasn't being applied at library root level * Added a notification for when a device is being sent a file. * Added a check in forgot password for users that do not have an email set or aren't confirmed. * Added a new api for change email and moved change password directly into new Account tab (styling and logic needs testing) * Save approx scroll position like with jump key, but on normal click of card. * Implemented the ability to change your email address or set one. This requires a 2 step process using a confirmation token. This needs polishing and css. * Removed an unused directive from codebase * Fixed up some typos on publicly * Updated query for Pending Invites to also check if the user account has not logged in at least once. * Cleaned up the css for validate email change * Hooked in an indicator to tell user that a user has an unconfirmed email * Cleaned up code smells
This commit is contained in:
parent
3792ac3421
commit
5f17c2fb73
49 changed files with 816 additions and 274 deletions
|
@ -0,0 +1,82 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { map, Observable, of, shareReplay, Subject, takeUntil } from 'rxjs';
|
||||
import { User } from 'src/app/_models/user';
|
||||
import { AccountService } from 'src/app/_services/account.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-change-password',
|
||||
templateUrl: './change-password.component.html',
|
||||
styleUrls: ['./change-password.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ChangePasswordComponent implements OnInit, OnDestroy {
|
||||
|
||||
passwordChangeForm: FormGroup = new FormGroup({});
|
||||
user: User | undefined = undefined;
|
||||
hasChangePasswordAbility: Observable<boolean> = of(false);
|
||||
observableHandles: Array<any> = [];
|
||||
passwordsMatch = false;
|
||||
resetPasswordErrors: string[] = [];
|
||||
isViewMode: boolean = true;
|
||||
|
||||
public get password() { return this.passwordChangeForm.get('password'); }
|
||||
public get confirmPassword() { return this.passwordChangeForm.get('confirmPassword'); }
|
||||
|
||||
private onDestroy = new Subject<void>();
|
||||
|
||||
constructor(private accountService: AccountService, private toastr: ToastrService, private readonly cdRef: ChangeDetectorRef) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.hasChangePasswordAbility = this.accountService.currentUser$.pipe(takeUntil(this.onDestroy), shareReplay(), map(user => {
|
||||
return user !== undefined && (this.accountService.hasAdminRole(user) || this.accountService.hasChangePasswordRole(user));
|
||||
}));
|
||||
this.cdRef.markForCheck();
|
||||
|
||||
this.passwordChangeForm.addControl('password', new FormControl('', [Validators.required]));
|
||||
this.passwordChangeForm.addControl('confirmPassword', new FormControl('', [Validators.required]));
|
||||
this.passwordChangeForm.addControl('oldPassword', new FormControl('', [Validators.required]));
|
||||
|
||||
|
||||
|
||||
this.observableHandles.push(this.passwordChangeForm.valueChanges.subscribe(() => {
|
||||
const values = this.passwordChangeForm.value;
|
||||
this.passwordsMatch = values.password === values.confirmPassword;
|
||||
this.cdRef.markForCheck();
|
||||
}));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.observableHandles.forEach(o => o.unsubscribe());
|
||||
this.onDestroy.next();
|
||||
this.onDestroy.complete();
|
||||
}
|
||||
|
||||
resetPasswordForm() {
|
||||
this.passwordChangeForm.get('password')?.setValue('');
|
||||
this.passwordChangeForm.get('confirmPassword')?.setValue('');
|
||||
this.passwordChangeForm.get('oldPassword')?.setValue('');
|
||||
this.resetPasswordErrors = [];
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
savePasswordForm() {
|
||||
if (this.user === undefined) { return; }
|
||||
|
||||
const model = this.passwordChangeForm.value;
|
||||
this.resetPasswordErrors = [];
|
||||
this.observableHandles.push(this.accountService.resetPassword(this.user?.username, model.confirmPassword, model.oldPassword).subscribe(() => {
|
||||
this.toastr.success('Password has been updated');
|
||||
this.resetPasswordForm();
|
||||
this.isViewMode = true;
|
||||
}, err => {
|
||||
this.resetPasswordErrors = err;
|
||||
}));
|
||||
}
|
||||
|
||||
toggleViewMode() {
|
||||
this.isViewMode = !this.isViewMode;
|
||||
this.resetPasswordForm();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue