Skip to content
Snippets Groups Projects
profile-page-security-form.component.ts 3.92 KiB
Newer Older
import { Component, Input, OnInit } from '@angular/core';
import {
  DynamicFormControlModel,
Kristof De Langhe's avatar
Kristof De Langhe committed
  DynamicFormService,
  DynamicInputModel
} from '@ng-dynamic-forms/core';
import { TranslateService } from '@ngx-translate/core';
import { FormGroup } from '@angular/forms';
Kristof De Langhe's avatar
Kristof De Langhe committed
import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
import { EPerson } from '../../core/eperson/models/eperson.model';
import { ErrorResponse, RestResponse } from '../../core/cache/response.models';
import { NotificationsService } from '../../shared/notifications/notifications.service';

@Component({
  selector: 'ds-profile-page-security-form',
  templateUrl: './profile-page-security-form.component.html'
})
/**
 * Component for a user to edit their security information
 * Displays a form containing a password field and a confirmation of the password
 */
export class ProfilePageSecurityFormComponent implements OnInit {
  /**
   * The user to display the form for
   */
  @Input() user: EPerson;
  /**
   * The form's input models
   */
  formModel: DynamicFormControlModel[] = [
    new DynamicInputModel({
      id: 'password',
      name: 'password',
      inputType: 'password'
    }),
    new DynamicInputModel({
      id: 'passwordrepeat',
      name: 'passwordrepeat',
      inputType: 'password'
    })
  ];

  /**
   * The form group of this form
   */
  formGroup: FormGroup;

  /**
   * Prefix for the notification messages of this component
   */
  NOTIFICATIONS_PREFIX = 'profile.security.form.notifications.';

  /**
   * Prefix for the form's label messages of this component
   */
  LABEL_PREFIX = 'profile.security.form.label.';

  constructor(protected formService: DynamicFormService,
              protected translate: TranslateService,
              protected epersonService: EPersonDataService,
              protected notificationsService: NotificationsService) {
    this.formGroup = this.formService.createFormGroup(this.formModel, { validators: this.checkPasswords });
    this.updateFieldTranslations();
    this.translate.onLangChange
      .subscribe(() => {
        this.updateFieldTranslations();
      });
  }

  /**
   * Update the translations of the field labels
   */
  updateFieldTranslations() {
    this.formModel.forEach(
      (fieldModel: DynamicInputModel) => {
        fieldModel.label = this.translate.instant(this.LABEL_PREFIX + fieldModel.id);
      }
    );
  }
  /**
   * Check if both password fields are filled in and equal
   * @param group The FormGroup to validate
   */
  checkPasswords(group: FormGroup) {
    const pass = group.get('password').value;
    const repeatPass = group.get('passwordrepeat').value;

    return isEmpty(repeatPass) || pass === repeatPass ? null : { notSame: true };
  }

  /**
   * Update the user's security details
   *
   * Sends a patch request for changing the user's password when a new password is present and the password confirmation
   * matches the new password.
   * Nothing happens when no passwords are filled in.
   * An error notification is displayed when the password confirmation does not match the new password.
   *
   * Returns false when nothing happened
   */
  updateSecurity() {
    const pass = this.formGroup.get('password').value;
    const passEntered = isNotEmpty(pass);
    if (!this.formGroup.valid) {
      if (passEntered) {
        this.notificationsService.error(this.translate.instant(this.NOTIFICATIONS_PREFIX + 'error.not-same'));
        return true;
      }
      return false;
    }
    if (passEntered) {
      const operation = Object.assign({ op: 'replace', path: '/password', value: pass });
      this.epersonService.patch(this.user.self, [operation]);
      this.notificationsService.success(
        this.translate.instant(this.NOTIFICATIONS_PREFIX + 'success.title'),
        this.translate.instant(this.NOTIFICATIONS_PREFIX + 'success.content')
      );