1<template>
2  <b-container fluid="xl">
3    <page-title />
4
5    <b-row>
6      <b-col md="8" lg="8" xl="6">
7        <page-section :section-title="$t('profileSettings.profileInfoTitle')">
8          <dl>
9            <dt>{{ $t('profileSettings.username') }}</dt>
10            <dd>
11              {{ username }}
12            </dd>
13          </dl>
14        </page-section>
15      </b-col>
16    </b-row>
17
18    <b-form @submit.prevent="submitForm">
19      <b-row>
20        <b-col sm="8" md="6" xl="3">
21          <page-section :section-title="$t('profileSettings.changePassword')">
22            <b-form-group
23              id="input-group-1"
24              :label="$t('profileSettings.newPassword')"
25              label-for="input-1"
26            >
27              <b-form-text id="password-help-block">
28                {{
29                  $t('pageLocalUserManagement.modal.passwordMustBeBetween', {
30                    min: passwordRequirements.minLength,
31                    max: passwordRequirements.maxLength
32                  })
33                }}
34              </b-form-text>
35              <input-password-toggle>
36                <b-form-input
37                  id="password"
38                  v-model="form.newPassword"
39                  type="password"
40                  aria-describedby="password-help-block"
41                  :state="getValidationState($v.form.newPassword)"
42                  @input="$v.form.newPassword.$touch()"
43                />
44                <b-form-invalid-feedback role="alert">
45                  <template v-if="!$v.form.newPassword.required">
46                    {{ $t('global.form.fieldRequired') }}
47                  </template>
48                  <template
49                    v-if="
50                      !$v.form.newPassword.minLength ||
51                        !$v.form.newPassword.maxLength
52                    "
53                  >
54                    {{
55                      $t('profileSettings.newPassLabelTextInfo', {
56                        min: passwordRequirements.minLength,
57                        max: passwordRequirements.maxLength
58                      })
59                    }}
60                  </template>
61                </b-form-invalid-feedback>
62              </input-password-toggle>
63            </b-form-group>
64            <b-form-group
65              id="input-group-2"
66              :label="$t('profileSettings.confirmPassword')"
67              label-for="input-2"
68            >
69              <input-password-toggle>
70                <b-form-input
71                  id="password-confirmation"
72                  v-model="form.confirmPassword"
73                  type="password"
74                  :state="getValidationState($v.form.confirmPassword)"
75                  @input="$v.form.confirmPassword.$touch()"
76                />
77                <b-form-invalid-feedback role="alert">
78                  <template v-if="!$v.form.confirmPassword.required">
79                    {{ $t('global.form.fieldRequired') }}
80                  </template>
81                  <template v-else-if="!$v.form.confirmPassword.sameAsPassword">
82                    {{ $t('profileSettings.passwordsDoNotMatch') }}
83                  </template>
84                </b-form-invalid-feedback>
85              </input-password-toggle>
86            </b-form-group>
87          </page-section>
88        </b-col>
89      </b-row>
90      <b-button variant="primary" type="submit">
91        {{ $t('global.action.save') }}
92      </b-button>
93    </b-form>
94  </b-container>
95</template>
96
97<script>
98import BVToastMixin from '@/components/Mixins/BVToastMixin';
99import InputPasswordToggle from '@/components/Global/InputPasswordToggle';
100import {
101  maxLength,
102  minLength,
103  required,
104  sameAs
105} from 'vuelidate/lib/validators';
106import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
107import PageTitle from '@/components/Global/PageTitle';
108import PageSection from '@/components/Global/PageSection';
109import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
110
111export default {
112  name: 'ProfileSettings',
113  components: { InputPasswordToggle, PageSection, PageTitle },
114  mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
115  data() {
116    return {
117      form: {
118        newPassword: '',
119        confirmPassword: ''
120      }
121    };
122  },
123  computed: {
124    username() {
125      return this.$store.getters['global/username'];
126    },
127    passwordRequirements() {
128      return this.$store.getters['localUsers/accountPasswordRequirements'];
129    }
130  },
131  created() {
132    this.startLoader();
133    this.$store
134      .dispatch('localUsers/getAccountSettings')
135      .finally(() => this.endLoader());
136  },
137  validations() {
138    return {
139      form: {
140        newPassword: {
141          required,
142          minLength: minLength(this.passwordRequirements.minLength),
143          maxLength: maxLength(this.passwordRequirements.maxLength)
144        },
145        confirmPassword: {
146          required,
147          sameAsPassword: sameAs('newPassword')
148        }
149      }
150    };
151  },
152  methods: {
153    submitForm() {
154      this.$v.$touch();
155      if (this.$v.$invalid) return;
156      let userData = {
157        originalUsername: this.username,
158        password: this.form.newPassword
159      };
160
161      this.$store
162        .dispatch('localUsers/updateUser', userData)
163        .then(message => {
164          (this.form.newPassword = ''), (this.form.confirmPassword = '');
165          this.$v.$reset();
166          this.successToast(message);
167        })
168        .catch(({ message }) => this.errorToast(message));
169    }
170  }
171};
172</script>
173