diff options
Diffstat (limited to 'src/views/AccessControl')
16 files changed, 0 insertions, 3592 deletions
diff --git a/src/views/AccessControl/ClientSessions/ClientSessions.vue b/src/views/AccessControl/ClientSessions/ClientSessions.vue deleted file mode 100644 index b61b2032..00000000 --- a/src/views/AccessControl/ClientSessions/ClientSessions.vue +++ /dev/null @@ -1,296 +0,0 @@ -<template> - <b-container fluid="xl"> - <page-title /> - <b-row class="align-items-end"> - <b-col sm="6" md="5" xl="4"> - <search - :placeholder="$t('pageClientSessions.table.searchSessions')" - data-test-id="clientSessions-input-searchSessions" - @change-search="onChangeSearchInput" - @clear-search="onClearSearchInput" - /> - </b-col> - <b-col sm="3" md="3" xl="2"> - <table-cell-count - :filtered-items-count="filteredRows" - :total-number-of-cells="allConnections.length" - ></table-cell-count> - </b-col> - </b-row> - <b-row> - <b-col> - <table-toolbar - ref="toolbar" - :selected-items-count="selectedRows.length" - :actions="batchActions" - @clear-selected="clearSelectedRows($refs.table)" - @batch-action="onBatchAction" - > - </table-toolbar> - <b-table - id="table-session-logs" - ref="table" - responsive="md" - selectable - no-select-on-click - hover - show-empty - sort-by="clientID" - :fields="fields" - :items="allConnections" - :filter="searchFilter" - :empty-text="$t('global.table.emptyMessage')" - :per-page="perPage" - :current-page="currentPage" - @filtered="onFiltered" - @row-selected="onRowSelected($event, allConnections.length)" - > - <!-- Checkbox column --> - <template #head(checkbox)> - <b-form-checkbox - v-model="tableHeaderCheckboxModel" - data-test-id="clientSessions-checkbox-selectAll" - :indeterminate="tableHeaderCheckboxIndeterminate" - @change="onChangeHeaderCheckbox($refs.table)" - > - <span class="sr-only">{{ $t('global.table.selectAll') }}</span> - </b-form-checkbox> - </template> - <template #cell(checkbox)="row"> - <b-form-checkbox - v-model="row.rowSelected" - :data-test-id="`clientSessions-checkbox-selectRow-${row.index}`" - @change="toggleSelectRow($refs.table, row.index)" - > - <span class="sr-only">{{ $t('global.table.selectItem') }}</span> - </b-form-checkbox> - </template> - - <!-- Actions column --> - <template #cell(actions)="row" class="ml-3"> - <table-row-action - v-for="(action, index) in row.item.actions" - :key="index" - :value="action.value" - :title="action.title" - :row-data="row.item" - :btn-icon-only="false" - :data-test-id="`clientSessions-button-disconnect-${row.index}`" - @click-table-action="onTableRowAction($event, row.item)" - ></table-row-action> - </template> - </b-table> - </b-col> - </b-row> - - <!-- Table pagination --> - <b-row> - <b-col sm="6"> - <b-form-group - class="table-pagination-select" - :label="$t('global.table.itemsPerPage')" - label-for="pagination-items-per-page" - > - <b-form-select - id="pagination-items-per-page" - v-model="perPage" - :options="itemsPerPageOptions" - /> - </b-form-group> - </b-col> - <b-col sm="6"> - <b-pagination - v-model="currentPage" - first-number - last-number - :per-page="perPage" - :total-rows="getTotalRowCount(allConnections.length)" - aria-controls="table-session-logs" - /> - </b-col> - </b-row> - </b-container> -</template> - -<script> -import PageTitle from '@/components/Global/PageTitle'; -import Search from '@/components/Global/Search'; -import TableCellCount from '@/components/Global/TableCellCount'; -import TableRowAction from '@/components/Global/TableRowAction'; -import TableToolbar from '@/components/Global/TableToolbar'; - -import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; -import BVPaginationMixin, { - currentPage, - perPage, - itemsPerPageOptions, -} from '@/components/Mixins/BVPaginationMixin'; -import BVTableSelectableMixin, { - selectedRows, - tableHeaderCheckboxModel, - tableHeaderCheckboxIndeterminate, -} from '@/components/Mixins/BVTableSelectableMixin'; -import BVToastMixin from '@/components/Mixins/BVToastMixin'; -import SearchFilterMixin, { - searchFilter, -} from '@/components/Mixins/SearchFilterMixin'; - -export default { - components: { - PageTitle, - Search, - TableCellCount, - TableRowAction, - TableToolbar, - }, - mixins: [ - BVPaginationMixin, - BVTableSelectableMixin, - BVToastMixin, - LoadingBarMixin, - SearchFilterMixin, - ], - beforeRouteLeave(to, from, next) { - // Hide loader if the user navigates to another page - // before request is fulfilled. - this.hideLoader(); - next(); - }, - data() { - return { - fields: [ - { - key: 'checkbox', - }, - { - key: 'clientID', - label: this.$t('pageClientSessions.table.clientID'), - }, - { - key: 'username', - label: this.$t('pageClientSessions.table.username'), - }, - { - key: 'ipAddress', - label: this.$t('pageClientSessions.table.ipAddress'), - }, - { - key: 'actions', - label: '', - }, - ], - batchActions: [ - { - value: 'disconnect', - label: this.$t('pageClientSessions.action.disconnect'), - }, - ], - currentPage: currentPage, - itemsPerPageOptions: itemsPerPageOptions, - perPage: perPage, - selectedRows: selectedRows, - searchTotalFilteredRows: 0, - tableHeaderCheckboxModel: tableHeaderCheckboxModel, - tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate, - searchFilter: searchFilter, - }; - }, - computed: { - filteredRows() { - return this.searchFilter - ? this.searchTotalFilteredRows - : this.allConnections.length; - }, - allConnections() { - return this.$store.getters['clientSessions/allConnections'].map( - (session) => { - return { - ...session, - actions: [ - { - value: 'disconnect', - title: this.$t('pageClientSessions.action.disconnect'), - }, - ], - }; - } - ); - }, - }, - created() { - this.startLoader(); - this.$store - .dispatch('clientSessions/getClientSessionsData') - .finally(() => this.endLoader()); - }, - methods: { - onFiltered(filteredItems) { - this.searchTotalFilteredRows = filteredItems.length; - }, - onChangeSearchInput(event) { - this.searchFilter = event; - }, - disconnectSessions(uris) { - this.$store - .dispatch('clientSessions/disconnectSessions', uris) - .then((messages) => { - messages.forEach(({ type, message }) => { - if (type === 'success') { - this.successToast(message); - } else if (type === 'error') { - this.errorToast(message); - } - }); - }); - }, - onTableRowAction(action, { uri }) { - if (action === 'disconnect') { - this.$bvModal - .msgBoxConfirm( - this.$tc('pageClientSessions.modal.disconnectMessage'), - { - title: this.$tc('pageClientSessions.modal.disconnectTitle'), - okTitle: this.$t('pageClientSessions.action.disconnect'), - cancelTitle: this.$t('global.action.cancel'), - } - ) - .then((deleteConfirmed) => { - if (deleteConfirmed) this.disconnectSessions([uri]); - }); - } - }, - onBatchAction(action) { - if (action === 'disconnect') { - const uris = this.selectedRows.map((row) => row.uri); - this.$bvModal - .msgBoxConfirm( - this.$tc( - 'pageClientSessions.modal.disconnectMessage', - this.selectedRows.length - ), - { - title: this.$tc( - 'pageClientSessions.modal.disconnectTitle', - this.selectedRows.length - ), - okTitle: this.$t('pageClientSessions.action.disconnect'), - cancelTitle: this.$t('global.action.cancel'), - } - ) - .then((deleteConfirmed) => { - if (deleteConfirmed) { - this.disconnectSessions(uris); - } - }); - } - }, - }, -}; -</script> -<style lang="scss"> -#table-session-logs { - td .btn-link { - width: auto !important; - } -} -</style> diff --git a/src/views/AccessControl/ClientSessions/index.js b/src/views/AccessControl/ClientSessions/index.js deleted file mode 100644 index 6000ab75..00000000 --- a/src/views/AccessControl/ClientSessions/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import ClientSessions from './ClientSessions.vue'; -export default ClientSessions; diff --git a/src/views/AccessControl/Ldap/Ldap.vue b/src/views/AccessControl/Ldap/Ldap.vue deleted file mode 100644 index 78bb830b..00000000 --- a/src/views/AccessControl/Ldap/Ldap.vue +++ /dev/null @@ -1,435 +0,0 @@ -<template> - <b-container fluid="xl"> - <page-title :description="$t('pageLdap.pageDescription')" /> - <page-section :section-title="$t('pageLdap.settings')"> - <b-form novalidate @submit.prevent="handleSubmit"> - <b-row> - <b-col> - <b-form-group - class="mb-3" - :label="$t('pageLdap.form.ldapAuthentication')" - :disabled="loading" - > - <b-form-checkbox - v-model="form.ldapAuthenticationEnabled" - data-test-id="ldap-checkbox-ldapAuthenticationEnabled" - @change="onChangeldapAuthenticationEnabled" - > - {{ $t('global.action.enable') }} - </b-form-checkbox> - </b-form-group> - </b-col> - </b-row> - <div class="form-background p-3"> - <b-form-group - class="m-0" - :label="$t('pageLdap.ariaLabel.ldapSettings')" - label-class="sr-only" - :disabled="!form.ldapAuthenticationEnabled || loading" - > - <b-row> - <b-col md="3" lg="4" xl="3"> - <b-form-group - class="mb-4" - :label="$t('pageLdap.form.secureLdapUsingSsl')" - > - <b-form-text id="enable-secure-help-block"> - {{ $t('pageLdap.form.secureLdapHelper') }} - </b-form-text> - <b-form-checkbox - id="enable-secure-ldap" - v-model="form.secureLdapEnabled" - aria-describedby="enable-secure-help-block" - data-test-id="ldap-checkbox-secureLdapEnabled" - :disabled=" - !caCertificateExpiration || !ldapCertificateExpiration - " - @change="$v.form.secureLdapEnabled.$touch()" - > - {{ $t('global.action.enable') }} - </b-form-checkbox> - </b-form-group> - <dl> - <dt>{{ $t('pageLdap.form.caCertificateValidUntil') }}</dt> - <dd v-if="caCertificateExpiration"> - {{ caCertificateExpiration | formatDate }} - </dd> - <dd v-else>--</dd> - <dt>{{ $t('pageLdap.form.ldapCertificateValidUntil') }}</dt> - <dd v-if="ldapCertificateExpiration"> - {{ ldapCertificateExpiration | formatDate }} - </dd> - <dd v-else>--</dd> - </dl> - <b-link - class="d-inline-block mb-4 m-md-0" - to="/access-control/ssl-certificates" - > - {{ $t('pageLdap.form.manageSslCertificates') }} - </b-link> - </b-col> - <b-col md="9" lg="8" xl="9"> - <b-row> - <b-col> - <b-form-group :label="$t('pageLdap.form.serviceType')"> - <b-form-radio - v-model="form.activeDirectoryEnabled" - data-test-id="ldap-radio-activeDirectoryEnabled" - :value="false" - @change="onChangeServiceType" - > - OpenLDAP - </b-form-radio> - <b-form-radio - v-model="form.activeDirectoryEnabled" - data-test-id="ldap-radio-activeDirectoryEnabled" - :value="true" - @change="onChangeServiceType" - > - Active Directory - </b-form-radio> - </b-form-group> - </b-col> - </b-row> - <b-row> - <b-col sm="6" xl="4"> - <b-form-group label-for="server-uri"> - <template #label> - {{ $t('pageLdap.form.serverUri') }} - <info-tooltip - :title="$t('pageLdap.form.serverUriTooltip')" - /> - </template> - <b-input-group :prepend="ldapProtocol"> - <b-form-input - id="server-uri" - v-model="form.serverUri" - data-test-id="ldap-input-serverUri" - :state="getValidationState($v.form.serverUri)" - @change="$v.form.serverUri.$touch()" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-input-group> - </b-form-group> - </b-col> - <b-col sm="6" xl="4"> - <b-form-group - :label="$t('pageLdap.form.bindDn')" - label-for="bind-dn" - > - <b-form-input - id="bind-dn" - v-model="form.bindDn" - data-test-id="ldap-input-bindDn" - :state="getValidationState($v.form.bindDn)" - @change="$v.form.bindDn.$touch()" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - <b-col sm="6" xl="4"> - <b-form-group - :label="$t('pageLdap.form.bindPassword')" - label-for="bind-password" - > - <input-password-toggle - data-test-id="ldap-input-togglePassword" - > - <b-form-input - id="bind-password" - v-model="form.bindPassword" - type="password" - :state="getValidationState($v.form.bindPassword)" - class="form-control-with-button" - @change="$v.form.bindPassword.$touch()" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </input-password-toggle> - </b-form-group> - </b-col> - <b-col sm="6" xl="4"> - <b-form-group - :label="$t('pageLdap.form.baseDn')" - label-for="base-dn" - > - <b-form-input - id="base-dn" - v-model="form.baseDn" - data-test-id="ldap-input-baseDn" - :state="getValidationState($v.form.baseDn)" - @change="$v.form.baseDn.$touch()" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - <b-col sm="6" xl="4"> - <b-form-group label-for="user-id-attribute"> - <template #label> - {{ $t('pageLdap.form.userIdAttribute') }} - - <span class="form-text d-inline"> - {{ $t('global.form.optional') }} - </span> - </template> - <b-form-input - id="user-id-attribute" - v-model="form.userIdAttribute" - data-test-id="ldap-input-userIdAttribute" - @change="$v.form.userIdAttribute.$touch()" - /> - </b-form-group> - </b-col> - <b-col sm="6" xl="4"> - <b-form-group label-for="group-id-attribute"> - <template #label> - {{ $t('pageLdap.form.groupIdAttribute') }} - - <span class="form-text d-inline"> - {{ $t('global.form.optional') }} - </span> - </template> - <b-form-input - id="group-id-attribute" - v-model="form.groupIdAttribute" - data-test-id="ldap-input-groupIdAttribute" - @change="$v.form.groupIdAttribute.$touch()" - /> - </b-form-group> - </b-col> - </b-row> - </b-col> - </b-row> - </b-form-group> - </div> - <b-row class="mt-4 mb-5"> - <b-col> - <b-btn - variant="primary" - type="submit" - data-test-id="ldap-button-saveSettings" - :disabled="loading" - > - {{ $t('global.action.saveSettings') }} - </b-btn> - </b-col> - </b-row> - </b-form> - </page-section> - - <!-- Role groups --> - <page-section :section-title="$t('pageLdap.roleGroups')"> - <table-role-groups /> - </page-section> - </b-container> -</template> - -<script> -import { mapGetters } from 'vuex'; -import { find } from 'lodash'; -import { requiredIf } from 'vuelidate/lib/validators'; - -import BVToastMixin from '@/components/Mixins/BVToastMixin'; -import VuelidateMixin from '@/components/Mixins/VuelidateMixin'; -import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin'; -import InputPasswordToggle from '@/components/Global/InputPasswordToggle'; -import PageTitle from '@/components/Global/PageTitle'; -import PageSection from '@/components/Global/PageSection'; -import InfoTooltip from '@/components/Global/InfoTooltip'; -import TableRoleGroups from './TableRoleGroups'; - -export default { - name: 'Ldap', - components: { - InfoTooltip, - InputPasswordToggle, - PageTitle, - PageSection, - TableRoleGroups, - }, - mixins: [BVToastMixin, VuelidateMixin, LoadingBarMixin], - beforeRouteLeave(to, from, next) { - this.hideLoader(); - next(); - }, - data() { - return { - form: { - ldapAuthenticationEnabled: this.$store.getters['ldap/isServiceEnabled'], - secureLdapEnabled: false, - activeDirectoryEnabled: this.$store.getters[ - 'ldap/isActiveDirectoryEnabled' - ], - serverUri: '', - bindDn: '', - bindPassword: '', - baseDn: '', - userIdAttribute: '', - groupIdAttribute: '', - loading, - }, - }; - }, - computed: { - ...mapGetters('ldap', [ - 'isServiceEnabled', - 'isActiveDirectoryEnabled', - 'ldap', - 'activeDirectory', - ]), - sslCertificates() { - return this.$store.getters['sslCertificates/allCertificates']; - }, - caCertificateExpiration() { - const caCertificate = find(this.sslCertificates, { - type: 'TrustStore Certificate', - }); - if (caCertificate === undefined) return null; - return caCertificate.validUntil; - }, - ldapCertificateExpiration() { - const ldapCertificate = find(this.sslCertificates, { - type: 'LDAP Certificate', - }); - if (ldapCertificate === undefined) return null; - return ldapCertificate.validUntil; - }, - ldapProtocol() { - return this.form.secureLdapEnabled ? 'ldaps://' : 'ldap://'; - }, - }, - watch: { - isServiceEnabled: function (value) { - this.form.ldapAuthenticationEnabled = value; - }, - isActiveDirectoryEnabled: function (value) { - this.form.activeDirectoryEnabled = value; - this.setFormValues(); - }, - }, - validations: { - form: { - ldapAuthenticationEnabled: {}, - secureLdapEnabled: {}, - activeDirectoryEnabled: { - required: requiredIf(function () { - return this.form.ldapAuthenticationEnabled; - }), - }, - serverUri: { - required: requiredIf(function () { - return this.form.ldapAuthenticationEnabled; - }), - }, - bindDn: { - required: requiredIf(function () { - return this.form.ldapAuthenticationEnabled; - }), - }, - bindPassword: { - required: requiredIf(function () { - return this.form.ldapAuthenticationEnabled; - }), - }, - baseDn: { - required: requiredIf(function () { - return this.form.ldapAuthenticationEnabled; - }), - }, - userIdAttribute: {}, - groupIdAttribute: {}, - }, - }, - created() { - this.startLoader(); - this.$store - .dispatch('ldap/getAccountSettings') - .finally(() => this.endLoader()); - this.$store - .dispatch('sslCertificates/getCertificates') - .finally(() => this.endLoader()); - this.setFormValues(); - }, - methods: { - setFormValues(serviceType) { - if (!serviceType) { - serviceType = this.isActiveDirectoryEnabled - ? this.activeDirectory - : this.ldap; - } - const { - serviceAddress = '', - bindDn = '', - baseDn = '', - userAttribute = '', - groupsAttribute = '', - } = serviceType; - const secureLdap = - serviceAddress && serviceAddress.includes('ldaps://') ? true : false; - const serverUri = serviceAddress - ? serviceAddress.replace(/ldaps?:\/\//, '') - : ''; - this.form.secureLdapEnabled = secureLdap; - this.form.serverUri = serverUri; - this.form.bindDn = bindDn; - this.form.bindPassword = ''; - this.form.baseDn = baseDn; - this.form.userIdAttribute = userAttribute; - this.form.groupIdAttribute = groupsAttribute; - }, - handleSubmit() { - this.$v.$touch(); - if (this.$v.$invalid) return; - const data = { - serviceEnabled: this.form.ldapAuthenticationEnabled, - activeDirectoryEnabled: this.form.activeDirectoryEnabled, - serviceAddress: `${this.ldapProtocol}${this.form.serverUri}`, - bindDn: this.form.bindDn, - bindPassword: this.form.bindPassword, - baseDn: this.form.baseDn, - userIdAttribute: this.form.userIdAttribute, - groupIdAttribute: this.form.groupIdAttribute, - }; - this.startLoader(); - this.$store - .dispatch('ldap/saveAccountSettings', data) - .then((success) => { - this.successToast(success); - }) - .catch(({ message }) => { - this.errorToast(message); - }) - .finally(() => { - this.form.bindPassword = ''; - this.$v.form.$reset(); - this.endLoader(); - }); - }, - onChangeServiceType(isActiveDirectoryEnabled) { - this.$v.form.activeDirectoryEnabled.$touch(); - const serviceType = isActiveDirectoryEnabled - ? this.activeDirectory - : this.ldap; - // Set form values according to user selected - // service type - this.setFormValues(serviceType); - }, - onChangeldapAuthenticationEnabled(isServiceEnabled) { - this.$v.form.ldapAuthenticationEnabled.$touch(); - if (!isServiceEnabled) { - // Request will fail if sent with empty values. - // The frontend only checks for required fields - // when the service is enabled. This is to prevent - // an error if a user clears any properties then - // disables the service. - this.setFormValues(); - } - }, - }, -}; -</script> diff --git a/src/views/AccessControl/Ldap/ModalAddRoleGroup.vue b/src/views/AccessControl/Ldap/ModalAddRoleGroup.vue deleted file mode 100644 index b6b77e9e..00000000 --- a/src/views/AccessControl/Ldap/ModalAddRoleGroup.vue +++ /dev/null @@ -1,164 +0,0 @@ -<template> - <b-modal id="modal-role-group" ref="modal" @ok="onOk" @hidden="resetForm"> - <template #modal-title> - <template v-if="roleGroup"> - {{ $t('pageLdap.modal.editRoleGroup') }} - </template> - <template v-else> - {{ $t('pageLdap.modal.addNewRoleGroup') }} - </template> - </template> - <b-container> - <b-row> - <b-col sm="8"> - <b-form id="role-group" @submit.prevent="handleSubmit"> - <!-- Edit role group --> - <template v-if="roleGroup !== null"> - <dl class="mb-4"> - <dt>{{ $t('pageLdap.modal.groupName') }}</dt> - <dd>{{ form.groupName }}</dd> - </dl> - </template> - - <!-- Add new role group --> - <template v-else> - <b-form-group - :label="$t('pageLdap.modal.groupName')" - label-for="role-group-name" - > - <b-form-input - id="role-group-name" - v-model="form.groupName" - :state="getValidationState($v.form.groupName)" - @input="$v.form.groupName.$touch()" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </template> - - <b-form-group - :label="$t('pageLdap.modal.groupPrivilege')" - label-for="privilege" - > - <b-form-select - id="privilege" - v-model="form.groupPrivilege" - :options="accountRoles" - :state="getValidationState($v.form.groupPrivilege)" - @input="$v.form.groupPrivilege.$touch()" - > - <template v-if="!roleGroup" #first> - <b-form-select-option :value="null" disabled> - {{ $t('global.form.selectAnOption') }} - </b-form-select-option> - </template> - </b-form-select> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-form> - </b-col> - </b-row> - </b-container> - <template #modal-footer="{ cancel }"> - <b-button variant="secondary" @click="cancel()"> - {{ $t('global.action.cancel') }} - </b-button> - <b-button form="role-group" type="submit" variant="primary" @click="onOk"> - <template v-if="roleGroup"> - {{ $t('global.action.save') }} - </template> - <template v-else> - {{ $t('global.action.add') }} - </template> - </b-button> - </template> - </b-modal> -</template> - -<script> -import { required, requiredIf } from 'vuelidate/lib/validators'; -import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; - -export default { - mixins: [VuelidateMixin], - props: { - roleGroup: { - type: Object, - default: null, - validator: (prop) => { - if (prop === null) return true; - return ( - Object.prototype.hasOwnProperty.call(prop, 'groupName') && - Object.prototype.hasOwnProperty.call(prop, 'groupPrivilege') - ); - }, - }, - }, - data() { - return { - form: { - groupName: null, - groupPrivilege: null, - }, - }; - }, - computed: { - accountRoles() { - return this.$store.getters['localUsers/accountRoles']; - }, - }, - watch: { - roleGroup: function (value) { - if (value === null) return; - this.form.groupName = value.groupName; - this.form.groupPrivilege = value.groupPrivilege; - }, - }, - validations() { - return { - form: { - groupName: { - required: requiredIf(function () { - return !this.roleGroup; - }), - }, - groupPrivilege: { - required, - }, - }, - }; - }, - methods: { - handleSubmit() { - this.$v.$touch(); - if (this.$v.$invalid) return; - this.$emit('ok', { - addNew: !this.roleGroup, - groupName: this.form.groupName, - groupPrivilege: this.form.groupPrivilege, - }); - this.closeModal(); - }, - closeModal() { - this.$nextTick(() => { - this.$refs.modal.hide(); - }); - }, - resetForm() { - this.form.groupName = null; - this.form.groupPrivilege = null; - this.$v.$reset(); - this.$emit('hidden'); - }, - onOk(bvModalEvt) { - // prevent modal close - bvModalEvt.preventDefault(); - this.handleSubmit(); - }, - }, -}; -</script> diff --git a/src/views/AccessControl/Ldap/TableRoleGroups.vue b/src/views/AccessControl/Ldap/TableRoleGroups.vue deleted file mode 100644 index 9d05ceaf..00000000 --- a/src/views/AccessControl/Ldap/TableRoleGroups.vue +++ /dev/null @@ -1,265 +0,0 @@ -<template> - <div> - <b-row> - <b-col md="9"> - <alert :show="isServiceEnabled === false" variant="info"> - {{ $t('pageLdap.tableRoleGroups.alertContent') }} - </alert> - </b-col> - </b-row> - <b-row> - <b-col class="text-right" md="9"> - <b-btn - variant="primary" - :disabled="!isServiceEnabled" - @click="initRoleGroupModal(null)" - > - <icon-add /> - {{ $t('pageLdap.addRoleGroup') }} - </b-btn> - </b-col> - </b-row> - <b-row> - <b-col md="9"> - <table-toolbar - ref="toolbar" - :selected-items-count="selectedRows.length" - :actions="batchActions" - @clear-selected="clearSelectedRows($refs.table)" - @batch-action="onBatchAction" - /> - <b-table - ref="table" - responsive - selectable - show-empty - no-select-on-click - hover - no-sort-reset - sort-icon-left - :items="tableItems" - :fields="fields" - :empty-text="$t('global.table.emptyMessage')" - @row-selected="onRowSelected($event, tableItems.length)" - > - <!-- Checkbox column --> - <template #head(checkbox)> - <b-form-checkbox - v-model="tableHeaderCheckboxModel" - :indeterminate="tableHeaderCheckboxIndeterminate" - :disabled="!isServiceEnabled" - @change="onChangeHeaderCheckbox($refs.table)" - > - <span class="sr-only">{{ $t('global.table.selectAll') }}</span> - </b-form-checkbox> - </template> - <template #cell(checkbox)="row"> - <b-form-checkbox - v-model="row.rowSelected" - :disabled="!isServiceEnabled" - @change="toggleSelectRow($refs.table, row.index)" - > - <span class="sr-only">{{ $t('global.table.selectItem') }}</span> - </b-form-checkbox> - </template> - - <!-- table actions column --> - <template #cell(actions)="{ item }"> - <table-row-action - v-for="(action, index) in item.actions" - :key="index" - :value="action.value" - :enabled="action.enabled" - :title="action.title" - @click-table-action="onTableRowAction($event, item)" - > - <template #icon> - <icon-edit v-if="action.value === 'edit'" /> - <icon-trashcan v-if="action.value === 'delete'" /> - </template> - </table-row-action> - </template> - </b-table> - </b-col> - </b-row> - <modal-add-role-group - :role-group="activeRoleGroup" - @ok="saveRoleGroup" - @hidden="activeRoleGroup = null" - /> - </div> -</template> - -<script> -import IconEdit from '@carbon/icons-vue/es/edit/20'; -import IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; -import IconAdd from '@carbon/icons-vue/es/add--alt/20'; -import { mapGetters } from 'vuex'; - -import Alert from '@/components/Global/Alert'; -import TableToolbar from '@/components/Global/TableToolbar'; -import TableRowAction from '@/components/Global/TableRowAction'; -import BVTableSelectableMixin, { - selectedRows, - tableHeaderCheckboxModel, - tableHeaderCheckboxIndeterminate, -} from '@/components/Mixins/BVTableSelectableMixin'; -import BVToastMixin from '@/components/Mixins/BVToastMixin'; -import ModalAddRoleGroup from './ModalAddRoleGroup'; -import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; - -export default { - components: { - Alert, - IconAdd, - IconEdit, - IconTrashcan, - ModalAddRoleGroup, - TableRowAction, - TableToolbar, - }, - mixins: [BVTableSelectableMixin, BVToastMixin, LoadingBarMixin], - data() { - return { - activeRoleGroup: null, - fields: [ - { - key: 'checkbox', - sortable: false, - }, - { - key: 'groupName', - sortable: true, - label: this.$t('pageLdap.tableRoleGroups.groupName'), - }, - { - key: 'groupPrivilege', - sortable: true, - label: this.$t('pageLdap.tableRoleGroups.groupPrivilege'), - }, - { - key: 'actions', - sortable: false, - label: '', - tdClass: 'text-right', - }, - ], - batchActions: [ - { - value: 'delete', - label: this.$t('global.action.delete'), - }, - ], - selectedRows: selectedRows, - tableHeaderCheckboxModel: tableHeaderCheckboxModel, - tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate, - }; - }, - computed: { - ...mapGetters('ldap', ['isServiceEnabled', 'enabledRoleGroups']), - tableItems() { - return this.enabledRoleGroups.map(({ LocalRole, RemoteGroup }) => { - return { - groupName: RemoteGroup, - groupPrivilege: LocalRole, - actions: [ - { - value: 'edit', - title: this.$t('global.action.edit'), - enabled: this.isServiceEnabled, - }, - { - value: 'delete', - title: this.$t('global.action.delete'), - enabled: this.isServiceEnabled, - }, - ], - }; - }); - }, - }, - created() { - this.$store.dispatch('localUsers/getAccountRoles'); - }, - methods: { - onBatchAction() { - this.$bvModal - .msgBoxConfirm( - this.$tc( - 'pageLdap.modal.deleteRoleGroupBatchConfirmMessage', - this.selectedRows.length - ), - { - title: this.$t('pageLdap.modal.deleteRoleGroup'), - okTitle: this.$t('global.action.delete'), - cancelTitle: this.$t('global.action.cancel'), - } - ) - .then((deleteConfirmed) => { - if (deleteConfirmed) { - this.startLoader(); - this.$store - .dispatch('ldap/deleteRoleGroup', { - roleGroups: this.selectedRows, - }) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - } - }); - }, - onTableRowAction(action, row) { - switch (action) { - case 'edit': - this.initRoleGroupModal(row); - break; - case 'delete': - this.$bvModal - .msgBoxConfirm( - this.$t('pageLdap.modal.deleteRoleGroupConfirmMessage', { - groupName: row.groupName, - }), - { - title: this.$t('pageLdap.modal.deleteRoleGroup'), - okTitle: this.$t('global.action.delete'), - cancelTitle: this.$t('global.action.cancel'), - } - ) - .then((deleteConfirmed) => { - if (deleteConfirmed) { - this.startLoader(); - this.$store - .dispatch('ldap/deleteRoleGroup', { roleGroups: [row] }) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - } - }); - break; - } - }, - initRoleGroupModal(roleGroup) { - this.activeRoleGroup = roleGroup; - this.$bvModal.show('modal-role-group'); - }, - saveRoleGroup({ addNew, groupName, groupPrivilege }) { - this.activeRoleGroup = null; - const data = { groupName, groupPrivilege }; - this.startLoader(); - if (addNew) { - this.$store - .dispatch('ldap/addNewRoleGroup', data) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - } else { - this.$store - .dispatch('ldap/saveRoleGroup', data) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - } - }, - }, -}; -</script> diff --git a/src/views/AccessControl/Ldap/index.js b/src/views/AccessControl/Ldap/index.js deleted file mode 100644 index 6ae3abfc..00000000 --- a/src/views/AccessControl/Ldap/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import Ldap from './Ldap.vue'; -export default Ldap; diff --git a/src/views/AccessControl/LocalUserManagement/LocalUserManagement.vue b/src/views/AccessControl/LocalUserManagement/LocalUserManagement.vue deleted file mode 100644 index fb5ba16e..00000000 --- a/src/views/AccessControl/LocalUserManagement/LocalUserManagement.vue +++ /dev/null @@ -1,386 +0,0 @@ -<template> - <b-container fluid="xl"> - <page-title /> - <b-row> - <b-col xl="9" class="text-right"> - <b-button variant="link" @click="initModalSettings"> - <icon-settings /> - {{ $t('pageLocalUserManagement.accountPolicySettings') }} - </b-button> - <b-button - variant="primary" - data-test-id="localUserManagement-button-addUser" - @click="initModalUser(null)" - > - <icon-add /> - {{ $t('pageLocalUserManagement.addUser') }} - </b-button> - </b-col> - </b-row> - <b-row> - <b-col xl="9"> - <table-toolbar - ref="toolbar" - :selected-items-count="selectedRows.length" - :actions="tableToolbarActions" - @clear-selected="clearSelectedRows($refs.table)" - @batch-action="onBatchAction" - /> - <b-table - ref="table" - responsive="md" - selectable - show-empty - no-select-on-click - hover - :fields="fields" - :items="tableItems" - :empty-text="$t('global.table.emptyMessage')" - @row-selected="onRowSelected($event, tableItems.length)" - > - <!-- Checkbox column --> - <template #head(checkbox)> - <b-form-checkbox - v-model="tableHeaderCheckboxModel" - data-test-id="localUserManagement-checkbox-tableHeaderCheckbox" - :indeterminate="tableHeaderCheckboxIndeterminate" - @change="onChangeHeaderCheckbox($refs.table)" - > - <span class="sr-only">{{ $t('global.table.selectAll') }}</span> - </b-form-checkbox> - </template> - <template #cell(checkbox)="row"> - <b-form-checkbox - v-model="row.rowSelected" - data-test-id="localUserManagement-checkbox-toggleSelectRow" - @change="toggleSelectRow($refs.table, row.index)" - > - <span class="sr-only">{{ $t('global.table.selectItem') }}</span> - </b-form-checkbox> - </template> - - <!-- table actions column --> - <template #cell(actions)="{ item }"> - <table-row-action - v-for="(action, index) in item.actions" - :key="index" - :value="action.value" - :enabled="action.enabled" - :title="action.title" - @click-table-action="onTableRowAction($event, item)" - > - <template #icon> - <icon-edit - v-if="action.value === 'edit'" - :data-test-id="`localUserManagement-tableRowAction-edit-${index}`" - /> - <icon-trashcan - v-if="action.value === 'delete'" - :data-test-id="`localUserManagement-tableRowAction-delete-${index}`" - /> - </template> - </table-row-action> - </template> - </b-table> - </b-col> - </b-row> - <b-row> - <b-col xl="8"> - <b-button - v-b-toggle.collapse-role-table - data-test-id="localUserManagement-button-viewPrivilegeRoleDescriptions" - variant="link" - class="mt-3" - > - <icon-chevron /> - {{ $t('pageLocalUserManagement.viewPrivilegeRoleDescriptions') }} - </b-button> - <b-collapse id="collapse-role-table" class="mt-3"> - <table-roles /> - </b-collapse> - </b-col> - </b-row> - <!-- Modals --> - <modal-settings :settings="settings" @ok="saveAccountSettings" /> - <modal-user - :user="activeUser" - :password-requirements="passwordRequirements" - @ok="saveUser" - @hidden="activeUser = null" - /> - </b-container> -</template> - -<script> -import IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; -import IconEdit from '@carbon/icons-vue/es/edit/20'; -import IconAdd from '@carbon/icons-vue/es/add--alt/20'; -import IconSettings from '@carbon/icons-vue/es/settings/20'; -import IconChevron from '@carbon/icons-vue/es/chevron--up/20'; - -import ModalUser from './ModalUser'; -import ModalSettings from './ModalSettings'; -import PageTitle from '@/components/Global/PageTitle'; -import TableRoles from './TableRoles'; -import TableToolbar from '@/components/Global/TableToolbar'; -import TableRowAction from '@/components/Global/TableRowAction'; - -import BVTableSelectableMixin, { - selectedRows, - tableHeaderCheckboxModel, - tableHeaderCheckboxIndeterminate, -} from '@/components/Mixins/BVTableSelectableMixin'; -import BVToastMixin from '@/components/Mixins/BVToastMixin'; -import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; - -export default { - name: 'LocalUsers', - components: { - IconAdd, - IconChevron, - IconEdit, - IconSettings, - IconTrashcan, - ModalSettings, - ModalUser, - PageTitle, - TableRoles, - TableRowAction, - TableToolbar, - }, - mixins: [BVTableSelectableMixin, BVToastMixin, LoadingBarMixin], - beforeRouteLeave(to, from, next) { - this.hideLoader(); - next(); - }, - data() { - return { - activeUser: null, - fields: [ - { - key: 'checkbox', - }, - { - key: 'username', - label: this.$t('pageLocalUserManagement.table.username'), - }, - { - key: 'privilege', - label: this.$t('pageLocalUserManagement.table.privilege'), - }, - { - key: 'status', - label: this.$t('pageLocalUserManagement.table.status'), - }, - { - key: 'actions', - label: '', - tdClass: 'text-right text-nowrap', - }, - ], - tableToolbarActions: [ - { - value: 'delete', - label: this.$t('global.action.delete'), - }, - { - value: 'enable', - label: this.$t('global.action.enable'), - }, - { - value: 'disable', - label: this.$t('global.action.disable'), - }, - ], - selectedRows: selectedRows, - tableHeaderCheckboxModel: tableHeaderCheckboxModel, - tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate, - }; - }, - computed: { - allUsers() { - return this.$store.getters['localUsers/allUsers']; - }, - tableItems() { - // transform user data to table data - return this.allUsers.map((user) => { - return { - username: user.UserName, - privilege: user.RoleId, - status: user.Locked - ? 'Locked' - : user.Enabled - ? 'Enabled' - : 'Disabled', - actions: [ - { - value: 'edit', - enabled: true, - title: this.$t('pageLocalUserManagement.editUser'), - }, - { - value: 'delete', - enabled: user.UserName === 'root' ? false : true, - title: this.$tc('pageLocalUserManagement.deleteUser'), - }, - ], - ...user, - }; - }); - }, - settings() { - return this.$store.getters['localUsers/accountSettings']; - }, - passwordRequirements() { - return this.$store.getters['localUsers/accountPasswordRequirements']; - }, - }, - created() { - this.startLoader(); - this.$store.dispatch('localUsers/getUsers').finally(() => this.endLoader()); - this.$store.dispatch('localUsers/getAccountSettings'); - this.$store.dispatch('localUsers/getAccountRoles'); - }, - methods: { - initModalUser(user) { - this.activeUser = user; - this.$bvModal.show('modal-user'); - }, - initModalDelete(user) { - this.$bvModal - .msgBoxConfirm( - this.$t('pageLocalUserManagement.modal.deleteConfirmMessage', { - user: user.username, - }), - { - title: this.$tc('pageLocalUserManagement.deleteUser'), - okTitle: this.$tc('pageLocalUserManagement.deleteUser'), - cancelTitle: this.$t('global.action.cancel'), - } - ) - .then((deleteConfirmed) => { - if (deleteConfirmed) { - this.deleteUser(user); - } - }); - }, - initModalSettings() { - this.$bvModal.show('modal-settings'); - }, - saveUser({ isNewUser, userData }) { - this.startLoader(); - if (isNewUser) { - this.$store - .dispatch('localUsers/createUser', userData) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - } else { - this.$store - .dispatch('localUsers/updateUser', userData) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - } - }, - deleteUser({ username }) { - this.startLoader(); - this.$store - .dispatch('localUsers/deleteUser', username) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - }, - onBatchAction(action) { - switch (action) { - case 'delete': - this.$bvModal - .msgBoxConfirm( - this.$tc( - 'pageLocalUserManagement.modal.batchDeleteConfirmMessage', - this.selectedRows.length - ), - { - title: this.$tc( - 'pageLocalUserManagement.deleteUser', - this.selectedRows.length - ), - okTitle: this.$tc( - 'pageLocalUserManagement.deleteUser', - this.selectedRows.length - ), - cancelTitle: this.$t('global.action.cancel'), - } - ) - .then((deleteConfirmed) => { - if (deleteConfirmed) { - this.startLoader(); - this.$store - .dispatch('localUsers/deleteUsers', this.selectedRows) - .then((messages) => { - messages.forEach(({ type, message }) => { - if (type === 'success') this.successToast(message); - if (type === 'error') this.errorToast(message); - }); - }) - .finally(() => this.endLoader()); - } - }); - break; - case 'enable': - this.startLoader(); - this.$store - .dispatch('localUsers/enableUsers', this.selectedRows) - .then((messages) => { - messages.forEach(({ type, message }) => { - if (type === 'success') this.successToast(message); - if (type === 'error') this.errorToast(message); - }); - }) - .finally(() => this.endLoader()); - break; - case 'disable': - this.startLoader(); - this.$store - .dispatch('localUsers/disableUsers', this.selectedRows) - .then((messages) => { - messages.forEach(({ type, message }) => { - if (type === 'success') this.successToast(message); - if (type === 'error') this.errorToast(message); - }); - }) - .finally(() => this.endLoader()); - break; - } - }, - onTableRowAction(action, row) { - switch (action) { - case 'edit': - this.initModalUser(row); - break; - case 'delete': - this.initModalDelete(row); - break; - default: - break; - } - }, - saveAccountSettings(settings) { - this.startLoader(); - this.$store - .dispatch('localUsers/saveAccountSettings', settings) - .then((message) => this.successToast(message)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - }, - }, -}; -</script> - -<style lang="scss" scoped> -.btn.collapsed { - svg { - transform: rotate(180deg); - } -} -</style> diff --git a/src/views/AccessControl/LocalUserManagement/ModalSettings.vue b/src/views/AccessControl/LocalUserManagement/ModalSettings.vue deleted file mode 100644 index bf274e5a..00000000 --- a/src/views/AccessControl/LocalUserManagement/ModalSettings.vue +++ /dev/null @@ -1,219 +0,0 @@ -<template> - <b-modal - id="modal-settings" - ref="modal" - :title="$t('pageLocalUserManagement.accountPolicySettings')" - @hidden="resetForm" - > - <b-form id="form-settings" novalidate @submit.prevent="handleSubmit"> - <b-container> - <b-row> - <b-col> - <b-form-group - :label=" - $t('pageLocalUserManagement.modal.maxFailedLoginAttempts') - " - label-for="lockout-threshold" - > - <b-form-text id="lockout-threshold-help-block"> - {{ - $t('global.form.valueMustBeBetween', { - min: 0, - max: 65535, - }) - }} - </b-form-text> - <b-form-input - id="lockout-threshold" - v-model.number="form.lockoutThreshold" - type="number" - aria-describedby="lockout-threshold-help-block" - data-test-id="localUserManagement-input-lockoutThreshold" - :state="getValidationState($v.form.lockoutThreshold)" - @input="$v.form.lockoutThreshold.$touch()" - /> - <b-form-invalid-feedback role="alert"> - <template v-if="!$v.form.lockoutThreshold.required"> - {{ $t('global.form.fieldRequired') }} - </template> - <template - v-if=" - !$v.form.lockoutThreshold.minLength || - !$v.form.lockoutThreshold.maxLength - " - > - {{ - $t('global.form.valueMustBeBetween', { - min: 0, - max: 65535, - }) - }} - </template> - </b-form-invalid-feedback> - </b-form-group> - </b-col> - <b-col> - <b-form-group - :label="$t('pageLocalUserManagement.modal.userUnlockMethod')" - > - <b-form-radio - v-model="form.unlockMethod" - name="unlock-method" - class="mb-2" - :value="0" - data-test-id="localUserManagement-radio-manualUnlock" - @input="$v.form.unlockMethod.$touch()" - > - {{ $t('pageLocalUserManagement.modal.manual') }} - </b-form-radio> - <b-form-radio - v-model="form.unlockMethod" - name="unlock-method" - :value="1" - data-test-id="localUserManagement-radio-automaticUnlock" - @input="$v.form.unlockMethod.$touch()" - > - {{ $t('pageLocalUserManagement.modal.automaticAfterTimeout') }} - </b-form-radio> - <div class="mt-3 ml-4"> - <b-form-text id="lockout-duration-help-block"> - {{ - $t('pageLocalUserManagement.modal.timeoutDurationSeconds') - }} - </b-form-text> - <b-form-input - v-model.number="form.lockoutDuration" - aria-describedby="lockout-duration-help-block" - type="number" - data-test-id="localUserManagement-input-lockoutDuration" - :state="getValidationState($v.form.lockoutDuration)" - :readonly="$v.form.unlockMethod.$model === 0" - @input="$v.form.lockoutDuration.$touch()" - /> - <b-form-invalid-feedback role="alert"> - <template v-if="!$v.form.lockoutDuration.required"> - {{ $t('global.form.fieldRequired') }} - </template> - <template v-else-if="!$v.form.lockoutDuration.minvalue"> - {{ $t('global.form.mustBeAtLeast', { value: 1 }) }} - </template> - </b-form-invalid-feedback> - </div> - </b-form-group> - </b-col> - </b-row> - </b-container> - </b-form> - <template #modal-footer="{ cancel }"> - <b-button - variant="secondary" - data-test-id="localUserManagement-button-cancel" - @click="cancel()" - > - {{ $t('global.action.cancel') }} - </b-button> - <b-button - form="form-settings" - type="submit" - variant="primary" - data-test-id="localUserManagement-button-submit" - @click="onOk" - > - {{ $t('global.action.save') }} - </b-button> - </template> - </b-modal> -</template> - -<script> -import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; -import { - required, - requiredIf, - minValue, - maxValue, -} from 'vuelidate/lib/validators'; - -export default { - mixins: [VuelidateMixin], - props: { - settings: { - type: Object, - required: true, - }, - }, - data() { - return { - form: { - lockoutThreshold: 0, - unlockMethod: 0, - lockoutDuration: null, - }, - }; - }, - watch: { - settings: function ({ lockoutThreshold, lockoutDuration }) { - this.form.lockoutThreshold = lockoutThreshold; - this.form.unlockMethod = lockoutDuration ? 1 : 0; - this.form.lockoutDuration = lockoutDuration ? lockoutDuration : null; - }, - }, - validations: { - form: { - lockoutThreshold: { - minValue: minValue(0), - maxValue: maxValue(65535), - required, - }, - unlockMethod: { required }, - lockoutDuration: { - minValue: function (value) { - return this.form.unlockMethod === 0 || value > 0; - }, - required: requiredIf(function () { - return this.form.unlockMethod === 1; - }), - }, - }, - }, - methods: { - handleSubmit() { - this.$v.$touch(); - if (this.$v.$invalid) return; - - let lockoutThreshold; - let lockoutDuration; - if (this.$v.form.lockoutThreshold.$dirty) { - lockoutThreshold = this.form.lockoutThreshold; - } - if (this.$v.form.unlockMethod.$dirty) { - lockoutDuration = this.form.unlockMethod - ? this.form.lockoutDuration - : 0; - } - - this.$emit('ok', { lockoutThreshold, lockoutDuration }); - this.closeModal(); - }, - onOk(bvModalEvt) { - // prevent modal close - bvModalEvt.preventDefault(); - this.handleSubmit(); - }, - closeModal() { - this.$nextTick(() => { - this.$refs.modal.hide(); - }); - }, - resetForm() { - // Reset form models - this.form.lockoutThreshold = this.settings.lockoutThreshold; - this.form.unlockMethod = this.settings.lockoutDuration ? 1 : 0; - this.form.lockoutDuration = this.settings.lockoutDuration - ? this.settings.lockoutDuration - : null; - this.$v.$reset(); // clear validations - }, - }, -}; -</script> diff --git a/src/views/AccessControl/LocalUserManagement/ModalUser.vue b/src/views/AccessControl/LocalUserManagement/ModalUser.vue deleted file mode 100644 index 202ae8e6..00000000 --- a/src/views/AccessControl/LocalUserManagement/ModalUser.vue +++ /dev/null @@ -1,395 +0,0 @@ -<template> - <b-modal id="modal-user" ref="modal" @hidden="resetForm"> - <template #modal-title> - <template v-if="newUser"> - {{ $t('pageLocalUserManagement.addUser') }} - </template> - <template v-else> - {{ $t('pageLocalUserManagement.editUser') }} - </template> - </template> - <b-form id="form-user" novalidate @submit.prevent="handleSubmit"> - <b-container> - <!-- Manual unlock form control --> - <b-row v-if="!newUser && manualUnlockPolicy && user.Locked"> - <b-col sm="9"> - <alert :show="true" variant="warning" small> - <template v-if="!$v.form.manualUnlock.$dirty"> - {{ $t('pageLocalUserManagement.modal.accountLocked') }} - </template> - <template v-else> - {{ - $t('pageLocalUserManagement.modal.clickSaveToUnlockAccount') - }} - </template> - </alert> - </b-col> - <b-col sm="3"> - <input - v-model="form.manualUnlock" - data-test-id="localUserManagement-input-manualUnlock" - type="hidden" - value="false" - /> - <b-button - variant="primary" - :disabled="$v.form.manualUnlock.$dirty" - data-test-id="localUserManagement-button-manualUnlock" - @click="$v.form.manualUnlock.$touch()" - > - {{ $t('pageLocalUserManagement.modal.unlock') }} - </b-button> - </b-col> - </b-row> - <b-row> - <b-col> - <b-form-group - :label="$t('pageLocalUserManagement.modal.accountStatus')" - > - <b-form-radio - v-model="form.status" - name="user-status" - :value="true" - data-test-id="localUserManagement-radioButton-statusEnabled" - @input="$v.form.status.$touch()" - > - {{ $t('global.status.enabled') }} - </b-form-radio> - <b-form-radio - v-model="form.status" - name="user-status" - data-test-id="localUserManagement-radioButton-statusDisabled" - :value="false" - @input="$v.form.status.$touch()" - > - {{ $t('global.status.disabled') }} - </b-form-radio> - </b-form-group> - <b-form-group - :label="$t('pageLocalUserManagement.modal.username')" - label-for="username" - > - <b-form-text id="username-help-block"> - {{ $t('pageLocalUserManagement.modal.cannotStartWithANumber') }} - <br /> - {{ - $t( - 'pageLocalUserManagement.modal.noSpecialCharactersExceptUnderscore' - ) - }} - </b-form-text> - <b-form-input - id="username" - v-model="form.username" - type="text" - aria-describedby="username-help-block" - data-test-id="localUserManagement-input-username" - :state="getValidationState($v.form.username)" - :disabled="!newUser && originalUsername === 'root'" - @input="$v.form.username.$touch()" - /> - <b-form-invalid-feedback role="alert"> - <template v-if="!$v.form.username.required"> - {{ $t('global.form.fieldRequired') }} - </template> - <template v-else-if="!$v.form.username.maxLength"> - {{ - $t('global.form.lengthMustBeBetween', { min: 1, max: 16 }) - }} - </template> - <template v-else-if="!$v.form.username.pattern"> - {{ $t('global.form.invalidFormat') }} - </template> - </b-form-invalid-feedback> - </b-form-group> - <b-form-group - :label="$t('pageLocalUserManagement.modal.privilege')" - label-for="privilege" - > - <b-form-select - id="privilege" - v-model="form.privilege" - :options="privilegeTypes" - data-test-id="localUserManagement-select-privilege" - :state="getValidationState($v.form.privilege)" - @input="$v.form.privilege.$touch()" - > - <template #first> - <b-form-select-option :value="null" disabled> - {{ $t('global.form.selectAnOption') }} - </b-form-select-option> - </template> - </b-form-select> - <b-form-invalid-feedback role="alert"> - <template v-if="!$v.form.privilege.required"> - {{ $t('global.form.fieldRequired') }} - </template> - </b-form-invalid-feedback> - </b-form-group> - </b-col> - <b-col> - <b-form-group - :label="$t('pageLocalUserManagement.modal.userPassword')" - label-for="password" - > - <b-form-text id="password-help-block"> - {{ - $t('pageLocalUserManagement.modal.passwordMustBeBetween', { - min: passwordRequirements.minLength, - max: passwordRequirements.maxLength, - }) - }} - </b-form-text> - <input-password-toggle> - <b-form-input - id="password" - v-model="form.password" - type="password" - data-test-id="localUserManagement-input-password" - aria-describedby="password-help-block" - :state="getValidationState($v.form.password)" - class="form-control-with-button" - @input="$v.form.password.$touch()" - /> - <b-form-invalid-feedback role="alert"> - <template v-if="!$v.form.password.required"> - {{ $t('global.form.fieldRequired') }} - </template> - <template - v-if=" - !$v.form.password.minLength || !$v.form.password.maxLength - " - > - {{ - $t( - 'pageLocalUserManagement.modal.passwordMustBeBetween', - { - min: passwordRequirements.minLength, - max: passwordRequirements.maxLength, - } - ) - }} - </template> - </b-form-invalid-feedback> - </input-password-toggle> - </b-form-group> - <b-form-group - :label="$t('pageLocalUserManagement.modal.confirmUserPassword')" - label-for="password-confirmation" - > - <input-password-toggle> - <b-form-input - id="password-confirmation" - v-model="form.passwordConfirmation" - data-test-id="localUserManagement-input-passwordConfirmation" - type="password" - :state="getValidationState($v.form.passwordConfirmation)" - class="form-control-with-button" - @input="$v.form.passwordConfirmation.$touch()" - /> - <b-form-invalid-feedback role="alert"> - <template v-if="!$v.form.passwordConfirmation.required"> - {{ $t('global.form.fieldRequired') }} - </template> - <template - v-else-if="!$v.form.passwordConfirmation.sameAsPassword" - > - {{ - $t('pageLocalUserManagement.modal.passwordsDoNotMatch') - }} - </template> - </b-form-invalid-feedback> - </input-password-toggle> - </b-form-group> - </b-col> - </b-row> - </b-container> - </b-form> - <template #modal-footer="{ cancel }"> - <b-button - variant="secondary" - data-test-id="localUserManagement-button-cancel" - @click="cancel()" - > - {{ $t('global.action.cancel') }} - </b-button> - <b-button - form="form-user" - data-test-id="localUserManagement-button-submit" - type="submit" - variant="primary" - @click="onOk" - > - <template v-if="newUser"> - {{ $t('pageLocalUserManagement.addUser') }} - </template> - <template v-else> - {{ $t('global.action.save') }} - </template> - </b-button> - </template> - </b-modal> -</template> - -<script> -import { - required, - maxLength, - minLength, - sameAs, - helpers, - requiredIf, -} from 'vuelidate/lib/validators'; -import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; -import InputPasswordToggle from '@/components/Global/InputPasswordToggle'; -import Alert from '@/components/Global/Alert'; - -export default { - components: { Alert, InputPasswordToggle }, - mixins: [VuelidateMixin], - props: { - user: { - type: Object, - default: null, - }, - passwordRequirements: { - type: Object, - required: true, - }, - }, - data() { - return { - originalUsername: '', - form: { - status: true, - username: '', - privilege: null, - password: '', - passwordConfirmation: '', - manualUnlock: false, - }, - }; - }, - computed: { - newUser() { - return this.user ? false : true; - }, - accountSettings() { - return this.$store.getters['localUsers/accountSettings']; - }, - manualUnlockPolicy() { - return !this.accountSettings.accountLockoutDuration; - }, - privilegeTypes() { - return this.$store.getters['localUsers/accountRoles']; - }, - }, - watch: { - user: function (value) { - if (value === null) return; - this.originalUsername = value.username; - this.form.username = value.username; - this.form.status = value.Enabled; - this.form.privilege = value.privilege; - }, - }, - validations() { - return { - form: { - status: { - required, - }, - username: { - required, - maxLength: maxLength(16), - pattern: helpers.regex('pattern', /^([a-zA-Z_][a-zA-Z0-9_]*)/), - }, - privilege: { - required, - }, - password: { - required: requiredIf(function () { - return this.requirePassword(); - }), - minLength: minLength(this.passwordRequirements.minLength), - maxLength: maxLength(this.passwordRequirements.maxLength), - }, - passwordConfirmation: { - required: requiredIf(function () { - return this.requirePassword(); - }), - sameAsPassword: sameAs('password'), - }, - manualUnlock: {}, - }, - }; - }, - methods: { - handleSubmit() { - let userData = {}; - - if (this.newUser) { - this.$v.$touch(); - if (this.$v.$invalid) return; - userData.username = this.form.username; - userData.status = this.form.status; - userData.privilege = this.form.privilege; - userData.password = this.form.password; - } else { - if (this.$v.$invalid) return; - userData.originalUsername = this.originalUsername; - if (this.$v.form.status.$dirty) { - userData.status = this.form.status; - } - if (this.$v.form.username.$dirty) { - userData.username = this.form.username; - } - if (this.$v.form.privilege.$dirty) { - userData.privilege = this.form.privilege; - } - if (this.$v.form.password.$dirty) { - userData.password = this.form.password; - } - if (this.$v.form.manualUnlock.$dirty) { - // If form manualUnlock control $dirty then - // set user Locked property to false - userData.locked = false; - } - if (Object.entries(userData).length === 1) { - this.closeModal(); - return; - } - } - - this.$emit('ok', { isNewUser: this.newUser, userData }); - this.closeModal(); - }, - closeModal() { - this.$nextTick(() => { - this.$refs.modal.hide(); - }); - }, - resetForm() { - this.form.originalUsername = ''; - this.form.status = true; - this.form.username = ''; - this.form.privilege = null; - this.form.password = ''; - this.form.passwordConfirmation = ''; - this.$v.$reset(); - this.$emit('hidden'); - }, - requirePassword() { - if (this.newUser) return true; - if (this.$v.form.password.$dirty) return true; - if (this.$v.form.passwordConfirmation.$dirty) return true; - return false; - }, - onOk(bvModalEvt) { - // prevent modal close - bvModalEvt.preventDefault(); - this.handleSubmit(); - }, - }, -}; -</script> diff --git a/src/views/AccessControl/LocalUserManagement/TableRoles.vue b/src/views/AccessControl/LocalUserManagement/TableRoles.vue deleted file mode 100644 index 3993af02..00000000 --- a/src/views/AccessControl/LocalUserManagement/TableRoles.vue +++ /dev/null @@ -1,92 +0,0 @@ -<template> - <b-table stacked="sm" hover small :items="items" :fields="fields"> - <template #cell(administrator)="data"> - <template v-if="data.value"> - <checkmark20 /> - </template> - </template> - <template #cell(operator)="data"> - <template v-if="data.value"> - <checkmark20 /> - </template> - </template> - <template #cell(readonly)="data"> - <template v-if="data.value"> - <checkmark20 /> - </template> - </template> - <template #cell(noaccess)="data"> - <template v-if="data.value"> - <checkmark20 /> - </template> - </template> - </b-table> -</template> - -<script> -import Checkmark20 from '@carbon/icons-vue/es/checkmark/20'; - -export default { - components: { - Checkmark20, - }, - data() { - return { - items: [ - { - description: this.$t( - 'pageLocalUserManagement.tableRoles.configureComponentsManagedByThisService' - ), - administrator: true, - operator: true, - readonly: false, - noaccess: false, - }, - { - description: this.$t( - 'pageLocalUserManagement.tableRoles.configureManagerResources' - ), - administrator: true, - operator: false, - readonly: false, - noaccess: false, - }, - { - description: this.$t( - 'pageLocalUserManagement.tableRoles.updatePasswordForCurrentUserAccount' - ), - administrator: true, - operator: true, - readonly: true, - noaccess: false, - }, - { - description: this.$t( - 'pageLocalUserManagement.tableRoles.configureUsersAndTheirAccounts' - ), - administrator: true, - operator: false, - readonly: false, - noaccess: false, - }, - { - description: this.$t( - 'pageLocalUserManagement.tableRoles.logInToTheServiceAndReadResources' - ), - administrator: true, - operator: true, - readonly: true, - noaccess: false, - }, - ], - fields: [ - { key: 'description', label: 'Privilege' }, - { key: 'administrator', label: 'Administrator', class: 'text-center' }, - { key: 'operator', label: 'Operator', class: 'text-center' }, - { key: 'readonly', label: 'ReadOnly', class: 'text-center' }, - { key: 'noaccess', label: 'NoAccess', class: 'text-center' }, - ], - }; - }, -}; -</script> diff --git a/src/views/AccessControl/LocalUserManagement/index.js b/src/views/AccessControl/LocalUserManagement/index.js deleted file mode 100644 index 315748af..00000000 --- a/src/views/AccessControl/LocalUserManagement/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import LocalUserManagement from './LocalUserManagement.vue'; -export default LocalUserManagement; diff --git a/src/views/AccessControl/SslCertificates/CsrCountryCodes.js b/src/views/AccessControl/SslCertificates/CsrCountryCodes.js deleted file mode 100644 index a2d70007..00000000 --- a/src/views/AccessControl/SslCertificates/CsrCountryCodes.js +++ /dev/null @@ -1,345 +0,0 @@ -import i18n from '@/i18n'; - -export const COUNTRY_LIST = [ - { name: 'Afghanistan', code: 'AF', label: i18n.t('countries.AF') }, - { name: 'Albania', code: 'AL', label: i18n.t('countries.AL') }, - { name: 'Algeria', code: 'DZ', label: i18n.t('countries.DZ') }, - { name: 'American Samoa', code: 'AS', label: i18n.t('countries.AS') }, - { name: 'Andorra', code: 'AD', label: i18n.t('countries.AD') }, - { name: 'Angola', code: 'AO', label: i18n.t('countries.AO') }, - { name: 'Anguilla', code: 'AI', label: i18n.t('countries.AI') }, - { name: 'Antarctica', code: 'AQ', label: i18n.t('countries.AQ') }, - { name: 'Antigua and Barbuda', code: 'AG', label: i18n.t('countries.AG') }, - { name: 'Argentina', code: 'AR', label: i18n.t('countries.AR') }, - { name: 'Armenia', code: 'AM', label: i18n.t('countries.AM') }, - { name: 'Aruba', code: 'AW', label: i18n.t('countries.AW') }, - { name: 'Australia', code: 'AU', label: i18n.t('countries.AU') }, - { name: 'Austria', code: 'AT', label: i18n.t('countries.AT') }, - { name: 'Azerbaijan', code: 'AZ', label: i18n.t('countries.AZ') }, - { name: 'Bahamas, The', code: 'BS', label: i18n.t('countries.BS') }, - { name: 'Bahrain', code: 'BH', label: i18n.t('countries.BH') }, - { name: 'Bangladesh', code: 'BD', label: i18n.t('countries.BD') }, - { name: 'Barbados', code: 'BB', label: i18n.t('countries.BB') }, - { name: 'Belarus', code: 'BY', label: i18n.t('countries.BY') }, - { name: 'Belgium', code: 'BE', label: i18n.t('countries.BE') }, - { name: 'Belize', code: 'BZ', label: i18n.t('countries.BZ') }, - { name: 'Benin', code: 'BJ', label: i18n.t('countries.BJ') }, - { name: 'Bermuda', code: 'BM', label: i18n.t('countries.BM') }, - { name: 'Bhutan', code: 'BT', label: i18n.t('countries.BT') }, - { name: 'Bolivia', code: 'BO', label: i18n.t('countries.BO') }, - { - name: 'Bonaire, Sint Eustatius and Saba', - code: 'BQ', - label: i18n.t('countries.BQ'), - }, - { - name: 'Bosnia and Herzegovina ', - code: 'BA', - label: i18n.t('countries.BA'), - }, - { name: 'Bostwana', code: 'BW', label: i18n.t('countries.BW') }, - { name: 'Bouvet Island', code: 'BV', label: i18n.t('countries.BV') }, - { name: 'Brazil', code: 'BR', label: i18n.t('countries.BR') }, - { - name: 'British Indian Ocean Territory', - code: 'IO', - label: i18n.t('countries.IO'), - }, - { name: 'Brunei Darussalam ', code: 'BN', label: i18n.t('countries.BN') }, - { name: 'Bulgaria', code: 'BG', label: i18n.t('countries.BG') }, - { name: 'Burkina Faso', code: 'BF', label: i18n.t('countries.BF') }, - { name: 'Burundi', code: 'BI', label: i18n.t('countries.BI') }, - { name: 'Cabo Verde', code: 'CV', label: i18n.t('countries.CV') }, - { name: 'Cambodia', code: 'KH', label: i18n.t('countries.KH') }, - { name: 'Cameroon', code: 'CM', label: i18n.t('countries.CM') }, - { name: 'Canada', code: 'CA', label: i18n.t('countries.CA') }, - { name: 'Cayman Islands', code: 'KY', label: i18n.t('countries.KY') }, - { - name: 'Central African Republic', - code: 'CF', - label: i18n.t('countries.CF'), - }, - { name: 'Chad', code: 'TD', label: i18n.t('countries.TD') }, - { name: 'Chile', code: 'CL', label: i18n.t('countries.CL') }, - { name: 'China', code: 'CN', label: i18n.t('countries.CN') }, - { name: 'Christmas Island ', code: 'CX', label: i18n.t('countries.CX') }, - { name: 'Cocos(Keeling) Islands', code: 'CC', label: i18n.t('countries.CC') }, - { name: 'Columbia', code: 'CO', label: i18n.t('countries.CO') }, - { name: 'Comoros', code: 'KM', label: i18n.t('countries.KM') }, - { - name: 'Congo, The Democratic Republic of the', - code: 'CD', - label: i18n.t('countries.CD'), - }, - { name: 'Congo', code: 'CG', label: i18n.t('countries.CG') }, - { name: 'Cook Islands', code: 'CK', label: i18n.t('countries.CK') }, - { name: 'Costa Rica', code: 'CR', label: i18n.t('countries.CR') }, - { name: 'Croatia', code: 'HR', label: i18n.t('countries.HR') }, - { name: 'Cuba', code: 'CU', label: i18n.t('countries.CU') }, - { name: 'Curaçao', code: 'CW', label: i18n.t('countries.CW') }, - { name: 'Cyprus', code: 'CY', label: i18n.t('countries.CY') }, - { name: 'Czechia', code: 'CZ', label: i18n.t('countries.CZ') }, - { name: "Côte d'Ivoire", code: 'CI', label: i18n.t('countries.CI') }, - { name: 'Denmark', code: 'DK', label: i18n.t('countries.DK') }, - { name: 'Djibouti', code: 'DJ', label: i18n.t('countries.DJ') }, - { name: 'Dominica', code: 'DM', label: i18n.t('countries.DM') }, - { name: 'Dominican Republic', code: 'DO', label: i18n.t('countries.DO') }, - { name: 'Ecuador', code: 'EC', label: i18n.t('countries.EC') }, - { name: 'Egypt', code: 'EG', label: i18n.t('countries.EG') }, - { name: 'El Salvador', code: 'SV', label: i18n.t('countries.SV') }, - { name: 'Equatorial Guinea ', code: 'GQ', label: i18n.t('countries.GQ') }, - { name: 'Eritrea', code: 'ER', label: i18n.t('countries.ER') }, - { name: 'Estonia', code: 'EE', label: i18n.t('countries.EE') }, - { name: 'Eswatini', code: 'SZ', label: i18n.t('countries.SZ') }, - { name: 'Ethiopia', code: 'ET', label: i18n.t('countries.ET') }, - { - name: 'Falkland Islands (Malvinas)', - code: 'FK', - label: i18n.t('countries.FK'), - }, - { name: 'Faroe Islands', code: 'FO', label: i18n.t('countries.FO') }, - { name: 'Fiji', code: 'FJ', label: i18n.t('countries.FJ') }, - { name: 'Finland', code: 'FI', label: i18n.t('countries.FI') }, - { name: 'France', code: 'FR', label: i18n.t('countries.FR') }, - { name: 'French Guiana', code: 'GF', label: i18n.t('countries.GF') }, - { name: 'French Polynesia', code: 'PF', label: i18n.t('countries.PF') }, - { - name: 'French Southern Territories', - code: 'TF', - label: i18n.t('countries.TF'), - }, - { name: 'Gabon', code: 'GA', label: i18n.t('countries.GA') }, - { name: 'Gambia, The', code: 'GM', label: i18n.t('countries.GM') }, - { name: 'Georgia', code: 'GE', label: i18n.t('countries.GE') }, - { name: 'Germany', code: 'DE', label: i18n.t('countries.DE') }, - { name: 'Ghana', code: 'GH', label: i18n.t('countries.GH') }, - { name: 'Gibraltar', code: 'GI', label: i18n.t('countries.GI') }, - { name: 'Greece', code: 'GR', label: i18n.t('countries.GR') }, - { name: 'Greenland', code: 'GL', label: i18n.t('countries.GL') }, - { name: 'Grenada', code: 'GD', label: i18n.t('countries.GD') }, - { name: 'Guadeloupe', code: 'GP', label: i18n.t('countries.GP') }, - { name: 'Guam', code: 'GU', label: i18n.t('countries.GU') }, - { name: 'Guatemala', code: 'GT', label: i18n.t('countries.GT') }, - { name: 'Guernsey', code: 'GG', label: i18n.t('countries.GG') }, - { name: 'Guinea', code: 'GN', label: i18n.t('countries.GN') }, - { name: 'Guinea-Bissau', code: 'GW', label: i18n.t('countries.GW') }, - { name: 'Guyana', code: 'GY', label: i18n.t('countries.GY') }, - { name: 'Haiti', code: 'HT', label: i18n.t('countries.HT') }, - { - name: 'Heard Island and McDonald Islands', - code: 'HM', - label: i18n.t('countries.HM'), - }, - { name: 'Holy See', code: 'VA', label: i18n.t('countries.VA') }, - { name: 'Honduras', code: 'HN', label: i18n.t('countries.HN') }, - { name: 'Hong Kong', code: 'HK', label: i18n.t('countries.HK') }, - { name: 'Hungary', code: 'HU', label: i18n.t('countries.HU') }, - { name: 'Iceland', code: 'IS', label: i18n.t('countries.IS') }, - { name: 'India', code: 'IN', label: i18n.t('countries.IN') }, - { name: 'Indonesia', code: 'ID', label: i18n.t('countries.ID') }, - { - name: 'Iran, Islamic Republic of', - code: 'IR', - label: i18n.t('countries.IR'), - }, - { name: 'Iraq', code: 'IQ', label: i18n.t('countries.IQ') }, - { name: 'Ireland', code: 'IE', label: i18n.t('countries.IE') }, - { name: 'Isle of Man', code: 'IM', label: i18n.t('countries.IM') }, - { name: 'Israel', code: 'IL', label: i18n.t('countries.IL') }, - { name: 'Italy', code: 'IT', label: i18n.t('countries.IT') }, - { name: 'Jamaica', code: 'JM', label: i18n.t('countries.JM') }, - { name: 'Japan', code: 'JP', label: i18n.t('countries.JP') }, - { name: 'Jersey', code: 'JE', label: i18n.t('countries.JE') }, - { name: 'Jordan', code: 'JO', label: i18n.t('countries.JO') }, - { name: 'Kazakhstan', code: 'KZ', label: i18n.t('countries.KZ') }, - { name: 'Kenya', code: 'KE', label: i18n.t('countries.KE') }, - { name: 'Kiribati', code: 'KI', label: i18n.t('countries.KI') }, - { name: 'Korea, Republic of', code: 'KR', label: i18n.t('countries.KR') }, - { - name: "Korea, Democratic People's Republic of", - code: 'KP', - label: i18n.t('countries.KP'), - }, - { name: 'Kuwait', code: 'KW', label: i18n.t('countries.KW') }, - { name: 'Kyrgyzstan', code: 'KG', label: i18n.t('countries.KG') }, - { - name: "Lao People's Democratic Republic", - code: 'LA', - label: i18n.t('countries.LA'), - }, - { name: 'Latvia', code: 'LV', label: i18n.t('countries.LV') }, - { name: 'Lebanon', code: 'LB', label: i18n.t('countries.LB') }, - { name: 'Lesotho', code: 'LS', label: i18n.t('countries.LS') }, - { name: 'Liberia', code: 'LR', label: i18n.t('countries.LR') }, - { name: 'Libya', code: 'LY', label: i18n.t('countries.LY') }, - { name: 'Liechtenstein', code: 'LI', label: i18n.t('countries.LI') }, - { name: 'Lithuania', code: 'LT', label: i18n.t('countries.LT') }, - { name: 'Luxembourg', code: 'LU', label: i18n.t('countries.LU') }, - { name: 'Macao', code: 'MO', label: i18n.t('countries.MO') }, - { - name: 'Macedonia, The Former Yugoslav Republic of', - code: 'MK', - label: i18n.t('countries.MK'), - }, - { name: 'Madagascar', code: 'MG', label: i18n.t('countries.MG') }, - { name: 'Malawi', code: 'MW', label: i18n.t('countries.MW') }, - { name: 'Malaysia', code: 'MY', label: i18n.t('countries.MY') }, - { name: 'Maldives', code: 'MV', label: i18n.t('countries.MV') }, - { name: 'Mali', code: 'ML', label: i18n.t('countries.ML') }, - { name: 'Malta', code: 'MT', label: i18n.t('countries.MT') }, - { name: 'Marshall Islands', code: 'MH', label: i18n.t('countries.MH') }, - { name: 'Martinique', code: 'MQ', label: i18n.t('countries.MQ') }, - { name: 'Mauritania', code: 'MR', label: i18n.t('countries.MR') }, - { name: 'Mauritius', code: 'MU', label: i18n.t('countries.MU') }, - { name: 'Mayotte', code: 'YT', label: i18n.t('countries.YT') }, - { name: 'Mexico', code: 'MX', label: i18n.t('countries.MX') }, - { - name: 'Micronesia, Federated States of', - code: 'FM', - label: i18n.t('countries.FM'), - }, - { name: 'Moldova, Republic of', code: 'MD', label: i18n.t('countries.MD') }, - { name: 'Monaco', code: 'MC', label: i18n.t('countries.MC') }, - { name: 'Mongolia', code: 'MN', label: i18n.t('countries.MN') }, - { name: 'Montenegro', code: 'ME', label: i18n.t('countries.ME') }, - { name: 'Montserrat', code: 'MS', label: i18n.t('countries.MS') }, - { name: 'Morocco', code: 'MA', label: i18n.t('countries.MA') }, - { name: 'Mozambique', code: 'MZ', label: i18n.t('countries.MZ') }, - { name: 'Myanmar', code: 'MM', label: i18n.t('countries.MM') }, - { name: 'Namibia', code: 'NA', label: i18n.t('countries.NA') }, - { name: 'Nauru', code: 'NR', label: i18n.t('countries.NR') }, - { name: 'Nepal', code: 'NP', label: i18n.t('countries.NP') }, - { name: 'Netherlands', code: 'NL', label: i18n.t('countries.NL') }, - { name: 'New Caledonia', code: 'NC', label: i18n.t('countries.NC') }, - { name: 'New Zealand', code: 'NZ', label: i18n.t('countries.NZ') }, - { name: 'Nicaragua', code: 'NI', label: i18n.t('countries.NI') }, - { name: 'Niger', code: 'NE', label: i18n.t('countries.NE') }, - { name: 'Nigeria', code: 'NG', label: i18n.t('countries.NG') }, - { name: 'Niue', code: 'NU', label: i18n.t('countries.NU') }, - { name: 'Norfolk Island', code: 'NF', label: i18n.t('countries.NF') }, - { - name: 'Northern Mariana Islands', - code: 'MP', - label: i18n.t('countries.MP'), - }, - { name: 'Norway', code: 'NO', label: i18n.t('countries.NO') }, - { name: 'Oman', code: 'OM', label: i18n.t('countries.OM') }, - { name: 'Pakistan', code: 'PK', label: i18n.t('countries.PK') }, - { name: 'Palau', code: 'PW', label: i18n.t('countries.PW') }, - { name: 'Palestine', code: 'PS', label: i18n.t('countries.PS') }, - { name: 'Panama', code: 'PA', label: i18n.t('countries.PA') }, - { name: 'Papua New Guinea', code: 'PG', label: i18n.t('countries.PG') }, - { name: 'Paraguay', code: 'PY', label: i18n.t('countries.PY') }, - { name: 'Peru', code: 'PE', label: i18n.t('countries.PE') }, - { name: 'Philippines', code: 'PH', label: i18n.t('countries.PH') }, - { name: 'Pitcairn', code: 'PN', label: i18n.t('countries.PN') }, - { name: 'Poland', code: 'PL', label: i18n.t('countries.PL') }, - { name: 'Portugal', code: 'PT', label: i18n.t('countries.PT') }, - { name: 'Puerto Rico', code: 'PR', label: i18n.t('countries.PR') }, - { name: 'Qatar', code: 'QA', label: i18n.t('countries.QA') }, - { name: 'Romania', code: 'RO', label: i18n.t('countries.RO') }, - { name: 'Russian Federation', code: 'RU', label: i18n.t('countries.RU') }, - { name: 'Rwanda', code: 'RW', label: i18n.t('countries.RW') }, - { name: 'Réunion', code: 'RE', label: i18n.t('countries.RE') }, - { name: 'Saint Barthélemy', code: 'BL', label: i18n.t('countries.BL') }, - { - name: 'Saint Helena, Ascension and Tristan da Cunha', - code: 'SH', - label: i18n.t('countries.SH'), - }, - { name: 'Saint Kitts and Nevis ', code: 'KN', label: i18n.t('countries.KN') }, - { name: 'Saint Lucia', code: 'LC', label: i18n.t('countries.LC') }, - { name: 'Saint Martin', code: 'MF', label: i18n.t('countries.MF') }, - { - name: 'Saint Pierre and Miquelon', - code: 'PM', - label: i18n.t('countries.PM'), - }, - { - name: 'Saint Vincent and the Grenadines', - code: 'VC', - label: i18n.t('countries.VC'), - }, - { name: 'Samoa', code: 'WS', label: i18n.t('countries.WS') }, - { name: 'San Marino ', code: 'SM', label: i18n.t('countries.SM') }, - { name: 'Sao Tome and Principe', code: 'ST', label: i18n.t('countries.ST') }, - { name: 'Saudi Arabia', code: 'SA', label: i18n.t('countries.SA') }, - { name: 'Senegal', code: 'SN', label: i18n.t('countries.SN') }, - { name: 'Serbia', code: 'RS', label: i18n.t('countries.RS') }, - { name: 'Seychelles', code: 'SC', label: i18n.t('countries.SC') }, - { name: 'Sierra Leone', code: 'SL', label: i18n.t('countries.SL') }, - { name: 'Singapore', code: 'SG', label: i18n.t('countries.SG') }, - { name: 'Sint Maarten', code: 'SX', label: i18n.t('countries.SX') }, - { name: 'Slovakia', code: 'SK', label: i18n.t('countries.SK') }, - { name: 'Slovenia', code: 'SI', label: i18n.t('countries.SI') }, - { name: 'Solomon Islands', code: 'SB', label: i18n.t('countries.SB') }, - { name: 'Somalia', code: 'SO', label: i18n.t('countries.SO') }, - { name: 'South Africa ', code: 'ZA', label: i18n.t('countries.ZA') }, - { - name: 'South Georgia and the South Sandwich Islands', - code: 'GS', - label: i18n.t('countries.GS'), - }, - { name: 'South Sudan', code: 'SS', label: i18n.t('countries.SS') }, - { name: 'Spain', code: 'ES', label: i18n.t('countries.ES') }, - { name: 'Sri Lanka', code: 'LK', label: i18n.t('countries.LK') }, - { name: 'Sudan', code: 'SD', label: i18n.t('countries.SD') }, - { name: 'Suriname', code: 'SR', label: i18n.t('countries.SR') }, - { name: 'Svalbard and Jan Mayen', code: 'SJ', label: i18n.t('countries.SJ') }, - { name: 'Sweden', code: 'SE', label: i18n.t('countries.SE') }, - { name: 'Switzerland', code: 'CH', label: i18n.t('countries.CH') }, - { name: 'Syrian Arab Republic', code: 'SY', label: i18n.t('countries.SY') }, - { name: 'Taiwan', code: 'TW', label: i18n.t('countries.TW') }, - { name: 'Tajikistan', code: 'TJ', label: i18n.t('countries.TJ') }, - { - name: 'Tanzania, United Republic of', - code: 'TZ', - label: i18n.t('countries.TZ'), - }, - { name: 'Thailand', code: 'TH', label: i18n.t('countries.TH') }, - { name: 'Timor-Leste', code: 'TL', label: i18n.t('countries.TL') }, - { name: 'Togo', code: 'TG', label: i18n.t('countries.TG') }, - { name: 'Tokelau', code: 'TK', label: i18n.t('countries.TK') }, - { name: 'Tonga', code: 'TO', label: i18n.t('countries.TO') }, - { name: 'Trinidad and Tobago', code: 'TT', label: i18n.t('countries.TT') }, - { name: 'Tunisia', code: 'TN', label: i18n.t('countries.TN') }, - { name: 'Turkey', code: 'TR', label: i18n.t('countries.TR') }, - { name: 'Turkmenistan', code: 'TM', label: i18n.t('countries.TM') }, - { - name: 'Turks and Caicos Islands', - code: 'TC', - label: i18n.t('countries.TC'), - }, - { name: 'Tuvalu', code: 'TV', label: i18n.t('countries.TV') }, - { name: 'Uganda', code: 'UG', label: i18n.t('countries.UG') }, - { name: 'Ukraine', code: 'UA', label: i18n.t('countries.UA') }, - { name: 'United Arab Emirates', code: 'AE', label: i18n.t('countries.AE') }, - { name: 'United Kingdom', code: 'GB', label: i18n.t('countries.GB') }, - { - name: 'United States Minor Outlying Islands', - code: 'UM', - label: i18n.t('countries.UM'), - }, - { - name: 'United States of America', - code: 'US', - label: i18n.t('countries.US'), - }, - { name: 'Uruguay', code: 'UY', label: i18n.t('countries.UY') }, - { name: 'Uzbekistan', code: 'UZ', label: i18n.t('countries.UZ') }, - { name: 'Vanuatu', code: 'VU', label: i18n.t('countries.VU') }, - { name: 'Venezuela', code: 'VE', label: i18n.t('countries.VE') }, - { name: 'Viet Nam', code: 'VN', label: i18n.t('countries.VN') }, - { - name: 'Virgin Islands, British', - code: 'VG', - label: i18n.t('countries.VG'), - }, - { name: 'Virgin Islands, U.S', code: 'VI', label: i18n.t('countries.VI') }, - { name: 'Wallis and Futuna', code: 'WF', label: i18n.t('countries.WF') }, - { name: 'Western Sahara', code: 'EH', label: i18n.t('countries.EH') }, - { name: 'Yemen', code: 'YE', label: i18n.t('countries.YE') }, - { name: 'Zambia', code: 'ZM', label: i18n.t('countries.ZM') }, - { name: 'Zimbabwe', code: 'ZW', label: i18n.t('countries.ZW') }, - { name: 'Åland Islands', code: 'AX', label: i18n.t('countries.AX') }, -]; diff --git a/src/views/AccessControl/SslCertificates/ModalGenerateCsr.vue b/src/views/AccessControl/SslCertificates/ModalGenerateCsr.vue deleted file mode 100644 index 6544c2c4..00000000 --- a/src/views/AccessControl/SslCertificates/ModalGenerateCsr.vue +++ /dev/null @@ -1,500 +0,0 @@ -<template> - <div> - <b-modal - id="generate-csr" - ref="modal" - size="lg" - no-stacking - :title=" - $t('pageSslCertificates.modal.generateACertificateSigningRequest') - " - @ok="onOkGenerateCsrModal" - @cancel="resetForm" - @hidden="$v.$reset()" - > - <b-form id="generate-csr-form" novalidate @submit.prevent="handleSubmit"> - <b-container fluid> - <b-row> - <b-col lg="9"> - <b-row> - <b-col lg="6"> - <b-form-group - :label="$t('pageSslCertificates.modal.certificateType')" - label-for="certificate-type" - > - <b-form-select - id="certificate-type" - v-model="form.certificateType" - data-test-id="modalGenerateCsr-select-certificateType" - :options="certificateOptions" - :state="getValidationState($v.form.certificateType)" - @input="$v.form.certificateType.$touch()" - > - <template #first> - <b-form-select-option :value="null" disabled> - {{ $t('global.form.selectAnOption') }} - </b-form-select-option> - </template> - </b-form-select> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - <b-col lg="6"> - <b-form-group - :label="$t('pageSslCertificates.modal.country')" - label-for="country" - > - <b-form-select - id="country" - v-model="form.country" - data-test-id="modalGenerateCsr-select-country" - :options="countryOptions" - :state="getValidationState($v.form.country)" - @input="$v.form.country.$touch()" - > - <template #first> - <b-form-select-option :value="null" disabled> - {{ $t('global.form.selectAnOption') }} - </b-form-select-option> - </template> - </b-form-select> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - </b-row> - <b-row> - <b-col lg="6"> - <b-form-group - :label="$t('pageSslCertificates.modal.state')" - label-for="state" - > - <b-form-input - id="state" - v-model="form.state" - type="text" - data-test-id="modalGenerateCsr-input-state" - :state="getValidationState($v.form.state)" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - <b-col lg="6"> - <b-form-group - :label="$t('pageSslCertificates.modal.city')" - label-for="city" - > - <b-form-input - id="city" - v-model="form.city" - type="text" - data-test-id="modalGenerateCsr-input-city" - :state="getValidationState($v.form.city)" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - </b-row> - <b-row> - <b-col lg="6"> - <b-form-group - :label="$t('pageSslCertificates.modal.companyName')" - label-for="company-name" - > - <b-form-input - id="company-name" - v-model="form.companyName" - type="text" - data-test-id="modalGenerateCsr-input-companyName" - :state="getValidationState($v.form.companyName)" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - <b-col lg="6"> - <b-form-group - :label="$t('pageSslCertificates.modal.companyUnit')" - label-for="company-unit" - > - <b-form-input - id="company-unit" - v-model="form.companyUnit" - type="text" - data-test-id="modalGenerateCsr-input-companyUnit" - :state="getValidationState($v.form.companyUnit)" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - </b-row> - <b-row> - <b-col lg="6"> - <b-form-group - :label="$t('pageSslCertificates.modal.commonName')" - label-for="common-name" - > - <b-form-input - id="common-name" - v-model="form.commonName" - type="text" - data-test-id="modalGenerateCsr-input-commonName" - :state="getValidationState($v.form.commonName)" - /> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - <b-col lg="6"> - <b-form-group label-for="challenge-password"> - <template #label> - {{ $t('pageSslCertificates.modal.challengePassword') }} - - <span class="form-text d-inline"> - {{ $t('global.form.optional') }} - </span> - </template> - <b-form-input - id="challenge-password" - v-model="form.challengePassword" - type="text" - data-test-id="modalGenerateCsr-input-challengePassword" - /> - </b-form-group> - </b-col> - </b-row> - <b-row> - <b-col lg="6"> - <b-form-group label-for="contact-person"> - <template #label> - {{ $t('pageSslCertificates.modal.contactPerson') }} - - <span class="form-text d-inline"> - {{ $t('global.form.optional') }} - </span> - </template> - <b-form-input - id="contact-person" - v-model="form.contactPerson" - type="text" - data-test-id="modalGenerateCsr-input-contactPerson" - /> - </b-form-group> - </b-col> - <b-col lg="6"> - <b-form-group label-for="email-address"> - <template #label> - {{ $t('pageSslCertificates.modal.emailAddress') }} - - <span class="form-text d-inline"> - {{ $t('global.form.optional') }} - </span> - </template> - <b-form-input - id="email-address" - v-model="form.emailAddress" - type="text" - data-test-id="modalGenerateCsr-input-emailAddress" - /> - </b-form-group> - </b-col> - </b-row> - <b-row> - <b-col lg="12"> - <b-form-group label-for="alternate-name"> - <template #label> - {{ $t('pageSslCertificates.modal.alternateName') }} - - <span class="form-text d-inline"> - {{ $t('global.form.optional') }} - </span> - </template> - <b-form-text id="alternate-name-help-block"> - {{ - $t('pageSslCertificates.modal.alternateNameHelperText') - }} - </b-form-text> - <b-form-tags - v-model="form.alternateName" - :remove-on-delete="true" - :tag-pills="true" - input-id="alternate-name" - size="lg" - separator=" " - :input-attrs="{ - 'aria-describedby': 'alternate-name-help-block', - }" - :duplicate-tag-text=" - $t('pageSslCertificates.modal.duplicateAlternateName') - " - placeholder="" - data-test-id="modalGenerateCsr-input-alternateName" - > - <template #add-button-text> - <icon-add /> {{ $t('global.action.add') }} - </template> - </b-form-tags> - </b-form-group> - </b-col> - </b-row> - </b-col> - <b-col lg="3"> - <b-row> - <b-col lg="12"> - <p class="col-form-label"> - {{ $t('pageSslCertificates.modal.privateKey') }} - </p> - <b-form-group - :label="$t('pageSslCertificates.modal.keyPairAlgorithm')" - label-for="key-pair-algorithm" - > - <b-form-select - id="key-pair-algorithm" - v-model="form.keyPairAlgorithm" - data-test-id="modalGenerateCsr-select-keyPairAlgorithm" - :options="keyPairAlgorithmOptions" - :state="getValidationState($v.form.keyPairAlgorithm)" - @input="$v.form.keyPairAlgorithm.$touch()" - > - <template #first> - <b-form-select-option :value="null" disabled> - {{ $t('global.form.selectAnOption') }} - </b-form-select-option> - </template> - </b-form-select> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </b-col> - </b-row> - <b-row> - <b-col lg="12"> - <template v-if="$v.form.keyPairAlgorithm.$model === 'EC'"> - <b-form-group - :label="$t('pageSslCertificates.modal.keyCurveId')" - label-for="key-curve-id" - > - <b-form-select - id="key-curve-id" - v-model="form.keyCurveId" - data-test-id="modalGenerateCsr-select-keyCurveId" - :options="keyCurveIdOptions" - :state="getValidationState($v.form.keyCurveId)" - @input="$v.form.keyCurveId.$touch()" - > - <template #first> - <b-form-select-option :value="null" disabled> - {{ $t('global.form.selectAnOption') }} - </b-form-select-option> - </template> - </b-form-select> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </template> - <template v-if="$v.form.keyPairAlgorithm.$model === 'RSA'"> - <b-form-group - :label="$t('pageSslCertificates.modal.keyBitLength')" - label-for="key-bit-length" - > - <b-form-select - id="key-bit-length" - v-model="form.keyBitLength" - data-test-id="modalGenerateCsr-select-keyBitLength" - :options="keyBitLengthOptions" - :state="getValidationState($v.form.keyBitLength)" - @input="$v.form.keyBitLength.$touch()" - > - <template #first> - <b-form-select-option :value="null" disabled> - {{ $t('global.form.selectAnOption') }} - </b-form-select-option> - </template> - </b-form-select> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.fieldRequired') }} - </b-form-invalid-feedback> - </b-form-group> - </template> - </b-col> - </b-row> - </b-col> - </b-row> - </b-container> - </b-form> - <template #modal-footer="{ ok, cancel }"> - <b-button variant="secondary" @click="cancel()"> - {{ $t('global.action.cancel') }} - </b-button> - <b-button - form="generate-csr-form" - type="submit" - variant="primary" - data-test-id="modalGenerateCsr-button-ok" - @click="ok()" - > - {{ $t('pageSslCertificates.generateCsr') }} - </b-button> - </template> - </b-modal> - <b-modal - id="csr-string" - no-stacking - size="lg" - :title="$t('pageSslCertificates.modal.certificateSigningRequest')" - @hidden="onHiddenCsrStringModal" - > - {{ csrString }} - <template #modal-footer> - <b-btn variant="secondary" @click="copyCsrString"> - <template v-if="csrStringCopied"> - <icon-checkmark /> - {{ $t('global.status.copied') }} - </template> - <template v-else> - {{ $t('global.action.copy') }} - </template> - </b-btn> - <a - :href="`data:text/json;charset=utf-8,${csrString}`" - download="certificate.txt" - class="btn btn-primary" - > - {{ $t('global.action.download') }} - </a> - </template> - </b-modal> - </div> -</template> - -<script> -import IconAdd from '@carbon/icons-vue/es/add--alt/20'; -import IconCheckmark from '@carbon/icons-vue/es/checkmark/20'; - -import { required, requiredIf } from 'vuelidate/lib/validators'; - -import { COUNTRY_LIST } from './CsrCountryCodes'; -import { CERTIFICATE_TYPES } from '@/store/modules/AccessControl/SslCertificatesStore'; -import BVToastMixin from '@/components/Mixins/BVToastMixin'; -import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; - -export default { - name: 'ModalGenerateCsr', - components: { IconAdd, IconCheckmark }, - mixins: [BVToastMixin, VuelidateMixin], - data() { - return { - form: { - certificateType: null, - country: null, - state: null, - city: null, - companyName: null, - companyUnit: null, - commonName: null, - challengePassword: null, - contactPerson: null, - emailAddress: null, - alternateName: [], - keyPairAlgorithm: null, - keyCurveId: null, - keyBitLength: null, - }, - certificateOptions: CERTIFICATE_TYPES.reduce((arr, cert) => { - if (cert.type === 'TrustStore Certificate') return arr; - arr.push({ - text: cert.label, - value: cert.type, - }); - return arr; - }, []), - countryOptions: COUNTRY_LIST.map((country) => ({ - text: country.label, - value: country.code, - })), - keyPairAlgorithmOptions: ['EC', 'RSA'], - keyCurveIdOptions: ['prime256v1', 'secp521r1', 'secp384r1'], - keyBitLengthOptions: [2048], - csrString: '', - csrStringCopied: false, - }; - }, - validations: { - form: { - certificateType: { required }, - country: { required }, - state: { required }, - city: { required }, - companyName: { required }, - companyUnit: { required }, - commonName: { required }, - challengePassword: {}, - contactPerson: {}, - emailAddress: {}, - alternateName: {}, - keyPairAlgorithm: { required }, - keyCurveId: { - reuired: requiredIf(function (form) { - return form.keyPairAlgorithm === 'EC'; - }), - }, - keyBitLength: { - reuired: requiredIf(function (form) { - return form.keyPairAlgorithm === 'RSA'; - }), - }, - }, - }, - methods: { - handleSubmit() { - this.$v.$touch(); - if (this.$v.$invalid) return; - this.$store - .dispatch('sslCertificates/generateCsr', this.form) - .then(({ data: { CSRString } }) => { - this.csrString = CSRString; - this.$bvModal.show('csr-string'); - this.$v.$reset(); - }); - }, - resetForm() { - for (let key of Object.keys(this.form)) { - if (key === 'alternateName') { - this.form[key] = []; - } else { - this.form[key] = null; - } - } - }, - onOkGenerateCsrModal(bvModalEvt) { - // prevent modal close - bvModalEvt.preventDefault(); - this.handleSubmit(); - }, - onHiddenCsrStringModal() { - this.csrString = ''; - this.resetForm(); - }, - copyCsrString(bvModalEvt) { - // prevent modal close - bvModalEvt.preventDefault(); - navigator.clipboard.writeText(this.csrString).then(() => { - // Show copied text for 5 seconds - this.csrStringCopied = true; - setTimeout(() => { - this.csrStringCopied = false; - }, 5000 /*5 seconds*/); - }); - }, - }, -}; -</script> diff --git a/src/views/AccessControl/SslCertificates/ModalUploadCertificate.vue b/src/views/AccessControl/SslCertificates/ModalUploadCertificate.vue deleted file mode 100644 index cafbd935..00000000 --- a/src/views/AccessControl/SslCertificates/ModalUploadCertificate.vue +++ /dev/null @@ -1,168 +0,0 @@ -<template> - <b-modal id="upload-certificate" ref="modal" @ok="onOk" @hidden="resetForm"> - <template #modal-title> - <template v-if="certificate"> - {{ $t('pageSslCertificates.replaceCertificate') }} - </template> - <template v-else> - {{ $t('pageSslCertificates.addNewCertificate') }} - </template> - </template> - <b-form> - <!-- Replace Certificate type --> - <template v-if="certificate !== null"> - <dl class="mb-4"> - <dt>{{ $t('pageSslCertificates.modal.certificateType') }}</dt> - <dd>{{ certificate.certificate }}</dd> - </dl> - </template> - - <!-- Add new Certificate type --> - <template v-else> - <b-form-group - :label="$t('pageSslCertificates.modal.certificateType')" - label-for="certificate-type" - > - <b-form-select - id="certificate-type" - v-model="form.certificateType" - :options="certificateOptions" - :state="getValidationState($v.form.certificateType)" - @input="$v.form.certificateType.$touch()" - > - </b-form-select> - <b-form-invalid-feedback role="alert"> - <template v-if="!$v.form.certificateType.required"> - {{ $t('global.form.fieldRequired') }} - </template> - </b-form-invalid-feedback> - </b-form-group> - </template> - - <b-form-group :label="$t('pageSslCertificates.modal.certificateFile')"> - <form-file - id="certificate-file" - v-model="form.file" - accept=".pem" - :state="getValidationState($v.form.file)" - > - <template #invalid> - <b-form-invalid-feedback role="alert"> - {{ $t('global.form.required') }} - </b-form-invalid-feedback> - </template> - </form-file> - </b-form-group> - </b-form> - <template #modal-ok> - <template v-if="certificate"> - {{ $t('global.action.replace') }} - </template> - <template v-else> - {{ $t('global.action.add') }} - </template> - </template> - <template #modal-cancel> - {{ $t('global.action.cancel') }} - </template> - </b-modal> -</template> - -<script> -import { required, requiredIf } from 'vuelidate/lib/validators'; -import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; - -import FormFile from '@/components/Global/FormFile'; - -export default { - components: { FormFile }, - mixins: [VuelidateMixin], - props: { - certificate: { - type: Object, - default: null, - validator: (prop) => { - if (prop === null) return true; - return ( - Object.prototype.hasOwnProperty.call(prop, 'type') && - Object.prototype.hasOwnProperty.call(prop, 'certificate') - ); - }, - }, - }, - data() { - return { - form: { - certificateType: null, - file: null, - }, - }; - }, - computed: { - certificateTypes() { - return this.$store.getters['sslCertificates/availableUploadTypes']; - }, - certificateOptions() { - return this.certificateTypes.map(({ type, label }) => { - return { - text: label, - value: type, - }; - }); - }, - }, - watch: { - certificateOptions: function (options) { - if (options.length) { - this.form.certificateType = options[0].value; - } - }, - }, - validations() { - return { - form: { - certificateType: { - required: requiredIf(function () { - return !this.certificate; - }), - }, - file: { - required, - }, - }, - }; - }, - methods: { - handleSubmit() { - this.$v.$touch(); - if (this.$v.$invalid) return; - this.$emit('ok', { - addNew: !this.certificate, - file: this.form.file, - location: this.certificate ? this.certificate.location : null, - type: this.certificate - ? this.certificate.type - : this.form.certificateType, - }); - this.closeModal(); - }, - closeModal() { - this.$nextTick(() => { - this.$refs.modal.hide(); - }); - }, - resetForm() { - this.form.certificateType = this.certificateOptions.length - ? this.certificateOptions[0].value - : null; - this.form.file = null; - this.$v.$reset(); - }, - onOk(bvModalEvt) { - // prevent modal close - bvModalEvt.preventDefault(); - this.handleSubmit(); - }, - }, -}; -</script> diff --git a/src/views/AccessControl/SslCertificates/SslCertificates.vue b/src/views/AccessControl/SslCertificates/SslCertificates.vue deleted file mode 100644 index 4ce9a707..00000000 --- a/src/views/AccessControl/SslCertificates/SslCertificates.vue +++ /dev/null @@ -1,319 +0,0 @@ -<template> - <b-container fluid="xl"> - <page-title /> - <b-row> - <b-col xl="11"> - <!-- Expired certificates banner --> - <alert :show="expiredCertificateTypes.length > 0" variant="danger"> - <template v-if="expiredCertificateTypes.length > 1"> - {{ $t('pageSslCertificates.alert.certificatesExpiredMessage') }} - </template> - <template v-else> - {{ - $t('pageSslCertificates.alert.certificateExpiredMessage', { - certificate: expiredCertificateTypes[0], - }) - }} - </template> - </alert> - <!-- Expiring certificates banner --> - <alert :show="expiringCertificateTypes.length > 0" variant="warning"> - <template v-if="expiringCertificateTypes.length > 1"> - {{ $t('pageSslCertificates.alert.certificatesExpiringMessage') }} - </template> - <template v-else> - {{ - $t('pageSslCertificates.alert.certificateExpiringMessage', { - certificate: expiringCertificateTypes[0], - }) - }} - </template> - </alert> - </b-col> - </b-row> - <b-row> - <b-col xl="11" class="text-right"> - <b-button - v-b-modal.generate-csr - data-test-id="sslCertificates-button-generateCsr" - variant="link" - > - <icon-add /> - {{ $t('pageSslCertificates.generateCsr') }} - </b-button> - <b-button - variant="primary" - :disabled="certificatesForUpload.length === 0" - @click="initModalUploadCertificate(null)" - > - <icon-add /> - {{ $t('pageSslCertificates.addNewCertificate') }} - </b-button> - </b-col> - </b-row> - <b-row> - <b-col xl="11"> - <b-table - responsive="md" - show-empty - hover - :fields="fields" - :items="tableItems" - :empty-text="$t('global.table.emptyMessage')" - > - <template #cell(validFrom)="{ value }"> - {{ value | formatDate }} - </template> - - <template #cell(validUntil)="{ value }"> - <status-icon - v-if="getDaysUntilExpired(value) < 31" - :status="getIconStatus(value)" - /> - {{ value | formatDate }} - </template> - - <template #cell(actions)="{ value, item }"> - <table-row-action - v-for="(action, index) in value" - :key="index" - :value="action.value" - :title="action.title" - :enabled="action.enabled" - @click-table-action="onTableRowAction($event, item)" - > - <template #icon> - <icon-replace v-if="action.value === 'replace'" /> - <icon-trashcan v-if="action.value === 'delete'" /> - </template> - </table-row-action> - </template> - </b-table> - </b-col> - </b-row> - - <!-- Modals --> - <modal-upload-certificate :certificate="modalCertificate" @ok="onModalOk" /> - <modal-generate-csr /> - </b-container> -</template> - -<script> -import IconAdd from '@carbon/icons-vue/es/add--alt/20'; -import IconReplace from '@carbon/icons-vue/es/renew/20'; -import IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; - -import ModalGenerateCsr from './ModalGenerateCsr'; -import ModalUploadCertificate from './ModalUploadCertificate'; -import PageTitle from '@/components/Global/PageTitle'; -import TableRowAction from '@/components/Global/TableRowAction'; -import StatusIcon from '@/components/Global/StatusIcon'; -import Alert from '@/components/Global/Alert'; - -import BVToastMixin from '@/components/Mixins/BVToastMixin'; -import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; - -export default { - name: 'SslCertificates', - components: { - Alert, - IconAdd, - IconReplace, - IconTrashcan, - ModalGenerateCsr, - ModalUploadCertificate, - PageTitle, - StatusIcon, - TableRowAction, - }, - mixins: [BVToastMixin, LoadingBarMixin], - beforeRouteLeave(to, from, next) { - this.hideLoader(); - next(); - }, - data() { - return { - modalCertificate: null, - fields: [ - { - key: 'certificate', - label: this.$t('pageSslCertificates.table.certificate'), - }, - { - key: 'issuedBy', - label: this.$t('pageSslCertificates.table.issuedBy'), - }, - { - key: 'issuedTo', - label: this.$t('pageSslCertificates.table.issuedTo'), - }, - { - key: 'validFrom', - label: this.$t('pageSslCertificates.table.validFrom'), - }, - { - key: 'validUntil', - label: this.$t('pageSslCertificates.table.validUntil'), - }, - { - key: 'actions', - label: '', - tdClass: 'text-right text-nowrap', - }, - ], - }; - }, - computed: { - certificates() { - return this.$store.getters['sslCertificates/allCertificates']; - }, - tableItems() { - return this.certificates.map((certificate) => { - return { - ...certificate, - actions: [ - { - value: 'replace', - title: this.$t('pageSslCertificates.replaceCertificate'), - }, - { - value: 'delete', - title: this.$t('pageSslCertificates.deleteCertificate'), - enabled: - certificate.type === 'TrustStore Certificate' ? true : false, - }, - ], - }; - }); - }, - certificatesForUpload() { - return this.$store.getters['sslCertificates/availableUploadTypes']; - }, - bmcTime() { - return this.$store.getters['global/bmcTime']; - }, - expiredCertificateTypes() { - return this.certificates.reduce((acc, val) => { - const daysUntilExpired = this.getDaysUntilExpired(val.validUntil); - if (daysUntilExpired < 1) { - acc.push(val.certificate); - } - return acc; - }, []); - }, - expiringCertificateTypes() { - return this.certificates.reduce((acc, val) => { - const daysUntilExpired = this.getDaysUntilExpired(val.validUntil); - if (daysUntilExpired < 31 && daysUntilExpired > 0) { - acc.push(val.certificate); - } - return acc; - }, []); - }, - }, - async created() { - this.startLoader(); - await this.$store.dispatch('global/getBmcTime'); - this.$store - .dispatch('sslCertificates/getCertificates') - .finally(() => this.endLoader()); - }, - methods: { - onTableRowAction(event, rowItem) { - switch (event) { - case 'replace': - this.initModalUploadCertificate(rowItem); - break; - case 'delete': - this.initModalDeleteCertificate(rowItem); - break; - default: - break; - } - }, - initModalUploadCertificate(certificate = null) { - this.modalCertificate = certificate; - this.$bvModal.show('upload-certificate'); - }, - initModalDeleteCertificate(certificate) { - this.$bvModal - .msgBoxConfirm( - this.$t('pageSslCertificates.modal.deleteConfirmMessage', { - issuedBy: certificate.issuedBy, - certificate: certificate.certificate, - }), - { - title: this.$t('pageSslCertificates.deleteCertificate'), - okTitle: this.$t('global.action.delete'), - cancelTitle: this.$t('global.action.cancel'), - } - ) - .then((deleteConfirmed) => { - if (deleteConfirmed) this.deleteCertificate(certificate); - }); - }, - onModalOk({ addNew, file, type, location }) { - if (addNew) { - // Upload a new certificate - this.addNewCertificate(file, type); - } else { - // Replace an existing certificate - this.replaceCertificate(file, type, location); - } - }, - addNewCertificate(file, type) { - this.startLoader(); - this.$store - .dispatch('sslCertificates/addNewCertificate', { file, type }) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - }, - replaceCertificate(file, type, location) { - this.startLoader(); - const reader = new FileReader(); - reader.readAsBinaryString(file); - reader.onloadend = (event) => { - const certificateString = event.target.result; - this.$store - .dispatch('sslCertificates/replaceCertificate', { - certificateString, - type, - location, - }) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - }; - }, - deleteCertificate({ type, location }) { - this.startLoader(); - this.$store - .dispatch('sslCertificates/deleteCertificate', { - type, - location, - }) - .then((success) => this.successToast(success)) - .catch(({ message }) => this.errorToast(message)) - .finally(() => this.endLoader()); - }, - getDaysUntilExpired(date) { - if (this.bmcTime) { - const validUntilMs = date.getTime(); - const currentBmcTimeMs = this.bmcTime.getTime(); - const oneDayInMs = 24 * 60 * 60 * 1000; - return Math.round((validUntilMs - currentBmcTimeMs) / oneDayInMs); - } - return new Date(); - }, - getIconStatus(date) { - const daysUntilExpired = this.getDaysUntilExpired(date); - if (daysUntilExpired < 1) { - return 'danger'; - } else if (daysUntilExpired < 31) { - return 'warning'; - } - }, - }, -}; -</script> diff --git a/src/views/AccessControl/SslCertificates/index.js b/src/views/AccessControl/SslCertificates/index.js deleted file mode 100644 index 03daa565..00000000 --- a/src/views/AccessControl/SslCertificates/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import SslCertificates from './SslCertificates.vue'; -export default SslCertificates; |