Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
<template>
<settings-certificates
:certificates-information="certificatesInformation"
:settings="commonSettings"
@certificate-generator="certificteGenerator"
@download-root-certificate="downloadRootCertificate"
/>
@delete-certificate="deleteCertificate"
@set-root-certificate="setRootCertificate"
>
<template #actions="{ newSettings, isDirty, validate }">
<u-btn :min-width="null" :disabled="!isDirty" @click="onSaveSettings(newSettings, validate)">{{
$t('save')
}}</u-btn>
</template>
</settings-certificates>
</template>

<script>
Expand All @@ -23,6 +31,9 @@
*/
certificatesInformation: ({ $store }) => $store.getters['config/certificatesInformation'],
rootCertificates: ({ $store }) => $store.getters['config/rootCertificates'],
commonSettings() {
return { certificatesInformation: this.certificatesInformation, rootCertificates: this.rootCertificates }
},
},

created() {
Expand All @@ -35,7 +46,7 @@
* @param {boolean} refetch - Whether to refetch the data from the server.
*/
async loadCertificates(refetch) {
await this.$store.dispatch('config/getCertificatesInformation', refetch)
await this.$store.dispatch('config/getRootCertificateInformation', refetch)
await this.$store.dispatch('config/getRootCertificateList', refetch)
},
/**
Expand Down Expand Up @@ -77,6 +88,47 @@
}
},

/**
* Sets the active root certificate.
* @param {string} payload.data.fileName - The name of the certificate file.
* @param {Function} payload.cb - Callback function to handle success or error.
*/
async setRootCertificate({ data, cb }) {
try {
await Rpc.asyncData('rpc.UvmContext.certificateManager.setActiveRootCertificate', data.fileName)
await this.loadCertificates(true)
cb(null, true) // success
} catch (err) {
Util.handleException(err)
cb(err, false) // error
}
},

/**
* Deletes a certificate.
* @param {Object} payload.data - Data containing the certificate details.
* @param {string} payload.certMode - The mode of the certificate (e.g., 'ROOT').
* @param {Function} payload.cb - Callback function to handle success or error.
*/
async deleteCertificate({ data, certMode, cb }) {
try {
const validation = this.canDeleteCertificate(data)

if (!validation.allowed) {
cb(validation.message, false)
return
}
await Rpc.asyncData('rpc.UvmContext.certificateManager.removeCertificate', certMode, data.fileName)
if (certMode === 'ROOT') {
await this.loadCertificates(true)
}
cb(null, true) // success
} catch (err) {
Util.handleException(err)
cb(err, false) // error
}
},

/* Optional hook triggered on browser refresh.
*/
onBrowserRefresh() {
Expand Down
4 changes: 2 additions & 2 deletions untangle-vue-ui/source/src/store/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const getters = {
/* Retrieves the certificates information from the state. */
certificatesInformation: state => state.certificatesInformation || {},
/* Retrieves the list of root certificates from the state. */
rootCertificates: state => state.rootCertificates || [],
rootCertificates: state => state.rootCertificates?.list || [],
}

const mutations = {
Expand Down Expand Up @@ -420,7 +420,7 @@ const actions = {

/* Get Certificate */

async getCertificatesInformation({ state, commit }, refetch) {
async getRootCertificateInformation({ state, commit }, refetch) {
if (state.certificatesInformation && !refetch) {
return
}
Expand Down
27 changes: 27 additions & 0 deletions untangle-vue-ui/source/src/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,33 @@ const util = {

return certSubject.join('')
},

/**
* Determines if a certificate can be deleted based on certain conditions.
* A certificate cannot be deleted if it's the system's Apache certificate ('apache.pem')
* or if it is assigned to one or more services (HTTPS, SMTPS, IPsec, RADIUS).
*
* @param {object} data - The certificate data object.
* @param {string} data.fileName - The file name of the certificate.
* @returns {{allowed: boolean, message?: string}} An object indicating if deletion is allowed and an optional error message.
*/
canDeleteCertificate(data) {
if (data.fileName === 'apache.pem') {
return {
allowed: false,
message: 'system_certificate_cannot_removed_error_message',
}
}

if (data.httpsServer || data.smtpsServer || data.ipsecServer || data.radiusServer) {
return {
allowed: false,
message: 'certificate_assigned_to_one_or_more_services_error_message',
}
}

return { allowed: true }
},
}

export default util