Support custom certificates for domains again
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
<script setup>
|
||||
|
||||
import { ref, useTemplateRef } from 'vue';
|
||||
import { Dialog, TextInput, FormGroup, Checkbox } from '@cloudron/pankow';
|
||||
import { Dialog, TextInput, InputGroup, FormGroup, Checkbox, Button } from '@cloudron/pankow';
|
||||
import { getTextFromFile } from '../utils.js';
|
||||
import DomainsModel from '../models/DomainsModel.js';
|
||||
import DomainProviderForm from './DomainProviderForm.vue';
|
||||
|
||||
@@ -10,6 +11,8 @@ const emit = defineEmits([ 'success' ]);
|
||||
const domainsModel = DomainsModel.create();
|
||||
|
||||
const dialog = useTemplateRef('dialog');
|
||||
const keyFileInput = useTemplateRef('keyFileInput');
|
||||
const certificateFileInput = useTemplateRef('certificateFileInput');
|
||||
|
||||
const busy = ref(false);
|
||||
const errorMessage = ref('');
|
||||
@@ -20,6 +23,8 @@ const provider = ref('');
|
||||
const tlsProvider = ref('letsencrypt-prod-wildcard');
|
||||
const showAdvanced = ref(false);
|
||||
const customNameservers = ref(false);
|
||||
const certificateFileName = ref('');
|
||||
const keyFileName = ref('');
|
||||
|
||||
const dnsConfig = ref(DomainsModel.createEmptyConfig());
|
||||
|
||||
@@ -49,8 +54,27 @@ async function onSubmit() {
|
||||
tlsConfig.wildcard = true;
|
||||
}
|
||||
|
||||
let fallbackCertificate = null;
|
||||
if (tlsConfig.provider === 'fallback') {
|
||||
const certFile = certificateFileInput.value.files[0] || null;
|
||||
const keyFile = keyFileInput.value.files[0] || null;
|
||||
|
||||
if ((!certFile && keyFile) || (certFile && !keyFile)) {
|
||||
errorMessage.value = 'Both certificate and key file need to be provided';
|
||||
busy.value = false;
|
||||
return;
|
||||
} else if (certFile && keyFile) {
|
||||
fallbackCertificate = {
|
||||
cert: await getTextFromFile(certFile),
|
||||
key: await getTextFromFile(keyFile),
|
||||
};
|
||||
} else {
|
||||
// unchanged
|
||||
}
|
||||
}
|
||||
|
||||
const func = editing.value ? domainsModel.update : domainsModel.add;
|
||||
const [error] = await func(domain.value, zoneName.value, provider.value, config, null, tlsConfig);
|
||||
const [error] = await func(domain.value, zoneName.value, provider.value, config, fallbackCertificate, tlsConfig);
|
||||
if (error) {
|
||||
errorMessage.value = error.body ? error.body.message : 'Internal error';
|
||||
busy.value = false;
|
||||
@@ -61,6 +85,20 @@ async function onSubmit() {
|
||||
dialog.value.close();
|
||||
}
|
||||
|
||||
function onCertificateFileChange() {
|
||||
const file = certificateFileInput.value.files[0] || '';
|
||||
if (!file) return;
|
||||
|
||||
certificateFileName.value = file ? file.name : '';
|
||||
}
|
||||
|
||||
function onKeyFileChange() {
|
||||
const file = keyFileInput.value.files[0] || '';
|
||||
if (!file) return;
|
||||
|
||||
keyFileName.value = file ? file.name : '';
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open(d) {
|
||||
d = d ? JSON.parse(JSON.stringify(d)) : { config: {}, tlsConfig: { provider: 'letsencrypt-prod', wildcard: true } }; // make a copy
|
||||
@@ -79,8 +117,9 @@ defineExpose({
|
||||
editing.value = !!d.domain;
|
||||
domain.value = d.domain || '';
|
||||
zoneName.value = d.zoneName || '';
|
||||
|
||||
customNameservers.value = d.config.customNameservers;
|
||||
certificateFileName.value = d.tlsConfig?.provider === 'fallback' ? String.fromCharCode(0x25CF).repeat(8) : '';
|
||||
keyFileName.value = d.tlsConfig?.provider === 'fallback' ? String.fromCharCode(0x25CF).repeat(8) : '';
|
||||
|
||||
dialog.value.open();
|
||||
|
||||
@@ -119,24 +158,27 @@ defineExpose({
|
||||
|
||||
<!-- custom certificate -->
|
||||
<div v-if="tlsProvider === 'fallback'">
|
||||
<label >{{ $t('domains.domainDialog.fallbackCertCustomCert') }}</label>
|
||||
<label>{{ $t('domains.domainDialog.fallbackCertCustomCert') }}</label>
|
||||
<p v-html="$t('domains.domainDialog.fallbackCertCustomCertInfo', { customCertLink: 'https://docs.cloudron.io/certificates/#custom-certificates' })"></p>
|
||||
</div>
|
||||
|
||||
<FormGroup v-if="tlsProvider === 'fallback'">
|
||||
<div class="input-group">
|
||||
<input type="file" id="fallbackCertFileInput" style="display:none"/>
|
||||
<input type="text" class="form-control" :placeholder="$t('domains.domainDialog.fallbackCertCertificatePlaceholder')" ng-model="domainConfigure.fallbackCert.certificateFileName" name="cert" onclick="getElementById('fallbackCertFileInput').click();" style="cursor: pointer;" ng-disabled="domainConfigure.busy">
|
||||
<span class="input-group-addon"><i class="fa fa-upload" onclick="getElementById('fallbackCertFileInput').click();"></i></span>
|
||||
<div v-if="tlsProvider === 'fallback'">
|
||||
<input type="file" ref="certificateFileInput" style="display: none" @change="onCertificateFileChange"/>
|
||||
<input type="file" ref="keyFileInput" style="display: none" @change="onKeyFileChange"/>
|
||||
|
||||
<div style="display: grid; grid-template-columns: auto 1fr; gap: 5px 10px">
|
||||
<label>{{ $t('domains.domainDialog.fallbackCertCertificatePlaceholder') }}</label>
|
||||
<InputGroup>
|
||||
<TextInput v-model="certificateFileName" @click="certificateFileInput.click()" style="cursor: pointer; flex-grow: 1;" :disabled="busy" />
|
||||
<Button tool secondary icon="fa-solid fa-upload" @click="certificateFileInput.click()"></Button>
|
||||
</InputGroup>
|
||||
<label>{{ $t('domains.domainDialog.fallbackCertKeyPlaceholder') }}</label>
|
||||
<InputGroup>
|
||||
<TextInput v-model="keyFileName" @click="keyFileInput.click()" style="cursor: pointer; flex-grow: 1;" :disabled="busy" />
|
||||
<Button tool secondary icon="fa-solid fa-upload" @click="keyFileInput.click()"></Button>
|
||||
</InputGroup>
|
||||
</div>
|
||||
</FormGroup>
|
||||
<FormGroup v-if="tlsProvider === 'fallback'">
|
||||
<div class="input-group">
|
||||
<input type="file" id="fallbackKeyFileInput" style="display:none"/>
|
||||
<input type="text" class="form-control" :placeholder="$t('domains.domainDialog.fallbackCertKeyPlaceholder')" ng-model="domainConfigure.fallbackCert.keyFileName" id="fallbackKeyInput" name="key" onclick="getElementById('fallbackKeyFileInput').click();" style="cursor: pointer;" ng-disabled="domainConfigure.busy">
|
||||
<span class="input-group-addon"><i class="fa fa-upload" onclick="getElementById('fallbackKeyFileInput').click();"></i></span>
|
||||
</div>
|
||||
</FormGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!showAdvanced" style="margin-top: 15px" class="actionable" @click="showAdvanced = true">{{ $t('domains.domainDialog.advancedAction') }}</div>
|
||||
|
||||
Reference in New Issue
Block a user