xref: /openbmc/webui-vue/src/views/SecurityAndAccess/UserManagement/ModalSettings.vue (revision d36ac8a8be8636ddd0e64ce005d507b21bcdeb00)
1<template>
2  <b-modal
3    id="modal-settings"
4    ref="modal"
5    :title="$t('pageUserManagement.accountPolicySettings')"
6    @hidden="resetForm"
7  >
8    <b-form id="form-settings" novalidate @submit.prevent="handleSubmit">
9      <b-container>
10        <b-row>
11          <b-col>
12            <b-form-group
13              :label="$t('pageUserManagement.modal.maxFailedLoginAttempts')"
14              label-for="lockout-threshold"
15            >
16              <b-form-text id="lockout-threshold-help-block">
17                {{
18                  $t('global.form.valueMustBeBetween', {
19                    min: 0,
20                    max: 65535,
21                  })
22                }}
23              </b-form-text>
24              <b-form-input
25                id="lockout-threshold"
26                v-model.number="form.lockoutThreshold"
27                type="number"
28                aria-describedby="lockout-threshold-help-block"
29                data-test-id="userManagement-input-lockoutThreshold"
30                :state="getValidationState(v$.form.lockoutThreshold)"
31                @input="v$.form.lockoutThreshold.$touch()"
32              />
33              <b-form-invalid-feedback role="alert">
34                <template v-if="v$.form.lockoutThreshold.required.$invalid">
35                  {{ $t('global.form.fieldRequired') }}
36                </template>
37                <template
38                  v-else-if="
39                    !v$.form.lockoutThreshold.minLength ||
40                    !v$.form.lockoutThreshold.maxLength
41                  "
42                >
43                  {{
44                    $t('global.form.valueMustBeBetween', {
45                      min: 0,
46                      max: 65535,
47                    })
48                  }}
49                </template>
50              </b-form-invalid-feedback>
51            </b-form-group>
52          </b-col>
53          <b-col>
54            <b-form-group
55              :label="$t('pageUserManagement.modal.userUnlockMethod')"
56            >
57              <b-form-radio
58                v-model="form.unlockMethod"
59                name="unlock-method"
60                class="mb-2"
61                :value="0"
62                data-test-id="userManagement-radio-manualUnlock"
63                @input="v$.form.unlockMethod.$touch()"
64              >
65                {{ $t('pageUserManagement.modal.manual') }}
66              </b-form-radio>
67              <b-form-radio
68                v-model="form.unlockMethod"
69                name="unlock-method"
70                :value="1"
71                data-test-id="userManagement-radio-automaticUnlock"
72                @input="v$.form.unlockMethod.$touch()"
73              >
74                {{ $t('pageUserManagement.modal.automaticAfterTimeout') }}
75              </b-form-radio>
76              <div class="mt-3 ml-4">
77                <b-form-text id="lockout-duration-help-block">
78                  {{ $t('pageUserManagement.modal.timeoutDurationSeconds') }}
79                </b-form-text>
80                <b-form-input
81                  v-model.number="form.lockoutDuration"
82                  aria-describedby="lockout-duration-help-block"
83                  type="number"
84                  data-test-id="userManagement-input-lockoutDuration"
85                  :state="getValidationState(v$.form.lockoutDuration)"
86                  :readonly="v$.form.unlockMethod.$model === 0"
87                  @input="v$.form.lockoutDuration.$touch()"
88                />
89                <b-form-invalid-feedback role="alert">
90                  <template v-if="v$.form.lockoutDuration.required.$invalid">
91                    {{ $t('global.form.fieldRequired') }}
92                  </template>
93                  <template v-else-if="!v$.form.lockoutDuration.minvalue">
94                    {{ $t('global.form.mustBeAtLeast', { value: 1 }) }}
95                  </template>
96                </b-form-invalid-feedback>
97              </div>
98            </b-form-group>
99          </b-col>
100        </b-row>
101      </b-container>
102    </b-form>
103    <template #footer="{ cancel }">
104      <b-button
105        variant="secondary"
106        data-test-id="userManagement-button-cancel"
107        @click="cancel()"
108      >
109        {{ $t('global.action.cancel') }}
110      </b-button>
111      <b-button
112        form="form-settings"
113        type="submit"
114        variant="primary"
115        data-test-id="userManagement-button-submit"
116        @click="onOk"
117      >
118        {{ $t('global.action.save') }}
119      </b-button>
120    </template>
121  </b-modal>
122</template>
123
124<script>
125import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
126import { useVuelidate } from '@vuelidate/core';
127import { useI18n } from 'vue-i18n';
128
129import {
130  required,
131  requiredIf,
132  minValue,
133  maxValue,
134} from '@vuelidate/validators';
135
136export default {
137  mixins: [VuelidateMixin],
138  props: {
139    settings: {
140      type: Object,
141      required: true,
142    },
143  },
144  emits: ['ok'],
145  setup() {
146    return {
147      v$: useVuelidate(),
148    };
149  },
150  data() {
151    return {
152      $t: useI18n().t,
153      form: {
154        lockoutThreshold: 0,
155        unlockMethod: 0,
156        lockoutDuration: null,
157      },
158    };
159  },
160  watch: {
161    settings: function ({ lockoutThreshold, lockoutDuration }) {
162      this.form.lockoutThreshold = lockoutThreshold;
163      this.form.unlockMethod = lockoutDuration ? 1 : 0;
164      this.form.lockoutDuration = lockoutDuration ? lockoutDuration : null;
165    },
166  },
167  validations: {
168    form: {
169      lockoutThreshold: {
170        minValue: minValue(0),
171        maxValue: maxValue(65535),
172        required,
173      },
174      unlockMethod: { required },
175      lockoutDuration: {
176        minValue: function (value) {
177          return this.form.unlockMethod === 0 || value > 0;
178        },
179        required: requiredIf(function () {
180          return this.form.unlockMethod === 1;
181        }),
182      },
183    },
184  },
185  methods: {
186    handleSubmit() {
187      this.v$.$touch();
188      if (this.v$.$invalid) return;
189
190      let lockoutThreshold;
191      let lockoutDuration;
192      if (this.v$.form.lockoutThreshold.$dirty) {
193        lockoutThreshold = this.form.lockoutThreshold;
194      }
195      if (this.v$.form.unlockMethod.$dirty) {
196        lockoutDuration = this.form.unlockMethod
197          ? parseInt(this.form.lockoutDuration)
198          : 0;
199      }
200
201      this.$emit('ok', { lockoutThreshold, lockoutDuration });
202      this.closeModal();
203    },
204    onOk(bvModalEvt) {
205      // prevent modal close
206      bvModalEvt.preventDefault();
207      this.handleSubmit();
208    },
209    closeModal() {
210      this.$nextTick(() => {
211        this.$refs.modal.hide();
212      });
213    },
214    resetForm() {
215      // Reset form models
216      this.form.lockoutThreshold = this.settings.lockoutThreshold;
217      this.form.unlockMethod = this.settings.lockoutDuration ? 1 : 0;
218      this.form.lockoutDuration = this.settings.lockoutDuration
219        ? this.settings.lockoutDuration
220        : null;
221      this.v$.$reset(); // clear validations
222    },
223  },
224};
225</script>
226