Request new certificate automatically after creating new alias

This commit is contained in:
Ralph J. Smit
2022-07-19 19:04:01 +02:00
parent 28ffc8e240
commit 77384a1abe
6 changed files with 195 additions and 42 deletions

View File

@@ -6,7 +6,6 @@ use App\Http\Requests\SiteAliasRequest;
use App\Http\Resources\SiteAliasResource;
use App\Jobs\Aliases\CreateAlias;
use App\Jobs\Aliases\DeleteAlias;
use Illuminate\Http\Request;
class SiteAliasController extends Controller
{
@@ -26,7 +25,7 @@ class SiteAliasController extends Controller
$site->addAlias($request->input('domain'));
dispatch(new CreateAlias($site, $request->input('domain')));
dispatch(new CreateAlias($site, $request->input('domain'), $request->boolean('request_new_certicate')));
return redirect()->route('sites.aliases.index', $id)->with('success', __('Alias has been created'));
}

View File

@@ -19,6 +19,9 @@ class SiteAliasRequest extends FormRequest
'required',
'string',
new Hostname,
],
'request_new_certicate' => [
'required',
]
];
}

View File

@@ -2,10 +2,12 @@
namespace App\Jobs\Aliases;
use App\Jobs\Certificates\CreateCertificate;
use App\Jobs\Certificates\DeleteCertificate;
use App\Models\Certificate;
use App\Models\Site;
use App\Traits\HasPloi;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
@@ -15,14 +17,11 @@ class CreateAlias implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
public Site $site;
public string $alias;
public function __construct(Site $site, $alias)
{
$this->site = $site;
$this->alias = $alias;
}
public function __construct(
public Site $site,
public string $alias,
public bool $requestNewCertificate = false,
) {}
public function handle()
{
@@ -31,6 +30,35 @@ class CreateAlias implements ShouldQueue
->sites($this->site->ploi_id)
->aliases()
->create([$this->alias]);
if ($this->requestNewCertificate) {
$currentCertificate = $this
->site
->certificates()
->whereIn('status', [Certificate::STATUS_ACTIVE, Certificate::STATUS_BUSY])
->latest()
->first();
if (! $currentCertificate) {
return;
}
dispatch(new DeleteCertificate($this->site->server->ploi_id, $this->site->ploi_id, $currentCertificate->ploi_id));
$newCertificate = $this->site->certificates()->create([
'domain' => $currentCertificate->domain . ',' . $this->alias,
'type' => $currentCertificate->type,
'certificate' => $currentCertificate->certificate,
'private' => $currentCertificate->private
]);
$currentCertificate->delete();
$newCertificate->server_id = $this->site->server_id;
$newCertificate->save();
dispatch(new CreateCertificate($newCertificate))->delay(now()->addSeconds(5));
}
}
public function failed()

3
public/css/app.css vendored
View File

@@ -1131,6 +1131,9 @@ select {
.mt-2 {
margin-top: 0.5rem;
}
.ml-4 {
margin-left: 1rem;
}
.block {
display: block;
}

View File

@@ -21,6 +21,7 @@
<template #form>
<form class="space-y-4" @submit.prevent="submit">
<FormInput :label="__('Domain')" :errors="$page.props.errors.domain" v-model="form.domain"/>
<FormCheckbox :label="__('Request new certificate')" :errors="$page.props.errors.request_new_certicate" v-model="form.request_new_certicate"/>
<FormActions>
<Button>{{ __('Save changes') }}</Button>
</FormActions>
@@ -66,38 +67,39 @@
</template>
<script>
import TopBar from './components/TopBar'
import Container from '@/components/Container'
import Content from '@/components/Content'
import Page from '@/components/Page'
import PageHeader from '@/components/PageHeader'
import PageHeaderTitle from '@/components/PageHeaderTitle'
import PageBody from '@/components/PageBody'
import Button from '@/components/Button'
import List from '@/components/List'
import ListItem from '@/components/ListItem'
import StatusBubble from '@/components/StatusBubble'
import NotificationBadge from '@/components/NotificationBadge'
import MainLayout from '@/Layouts/MainLayout'
import SettingsLayout from '@/components/layouts/SettingsLayout'
import SettingsSegment from '@/components/SettingsSegment'
import FormInput from '@/components/forms/FormInput'
import FormSelect from '@/components/forms/FormSelect'
import FormTextarea from '@/components/forms/FormTextarea'
import Form from '@/components/Form'
import Pagination from '@/components/Pagination'
import EmptyImage from '@/components/EmptyImage'
import FormActions from '@/components/FormActions'
import {useConfirm} from '@/hooks/confirm'
import Tabs from './Tabs'
import Table from '@/components/Table'
import TableHead from '@/components/TableHead'
import TableHeader from '@/components/TableHeader'
import TableRow from '@/components/TableRow'
import TableBody from '@/components/TableBody'
import TableData from '@/components/TableData'
import TopBar from './components/TopBar'
import Container from '@/components/Container'
import Content from '@/components/Content'
import Page from '@/components/Page'
import PageHeader from '@/components/PageHeader'
import PageHeaderTitle from '@/components/PageHeaderTitle'
import PageBody from '@/components/PageBody'
import Button from '@/components/Button'
import List from '@/components/List'
import ListItem from '@/components/ListItem'
import StatusBubble from '@/components/StatusBubble'
import NotificationBadge from '@/components/NotificationBadge'
import MainLayout from '@/Layouts/MainLayout'
import SettingsLayout from '@/components/layouts/SettingsLayout'
import SettingsSegment from '@/components/SettingsSegment'
import FormInput from '@/components/forms/FormInput'
import FormSelect from '@/components/forms/FormSelect'
import FormCheckbox from '@/components/forms/FormCheckbox'
import FormTextarea from '@/components/forms/FormTextarea'
import Form from '@/components/Form'
import Pagination from '@/components/Pagination'
import EmptyImage from '@/components/EmptyImage'
import FormActions from '@/components/FormActions'
import {useConfirm} from '@/hooks/confirm'
import Tabs from './Tabs'
import Table from '@/components/Table'
import TableHead from '@/components/TableHead'
import TableHeader from '@/components/TableHeader'
import TableRow from '@/components/TableRow'
import TableBody from '@/components/TableBody'
import TableData from '@/components/TableData'
export default {
export default {
metaInfo() {
return {
title: `${this.__('Certificates')} - ${this.site.domain}`,
@@ -120,6 +122,7 @@
StatusBubble,
NotificationBadge,
FormInput,
FormCheckbox,
FormSelect,
FormTextarea,
SettingsLayout,
@@ -143,6 +146,7 @@
form: {
domain: null,
request_new_certicate: false,
},
breadcrumbs: [
@@ -188,6 +192,7 @@
onFinish: () => {
this.sending = false
this.form.domain = null;
this.form.request_new_certicate = false;
}
});
},

View File

@@ -0,0 +1,115 @@
<template>
<FormGroup class="">
<div class="flex flex-row items-center">
<input :id="id"
:class="[
defaultClasses,
disabled || loading ? 'opacity-50' : '',
loading ? 'cursor-wait' : '',
]"
type="checkbox"
:required="required"
:value="value"
@input="updateValue($event.target.value)"
:disabled="loading || disabled"
:autofocus="autofocus"
:placeholder="placeholder" />
<ErrorText v-if="errors">{{ errors[0] }}</ErrorText>
<HelperText v-if="helperText && !errors">{{ helperText }}</HelperText>
<Label :errors="errors" :forId="id" class="ml-2">{{ label }}</Label>
</div>
</FormGroup>
</template>
<script>
import FormGroup from '@/components/FormGroup'
import Label from '@/components/Label'
import ErrorText from '@/components/ErrorText'
import HelperText from '@/components/HelperText'
import IconClipboard from '@/components/icons/IconClipboard'
import IconKey from '@/components/icons/IconKey'
const defaultClasses = ''
export default {
props: {
id: {
type: String,
required: false,
},
label: {
type: String,
required: true,
},
required: {
type: Boolean,
default: () => false,
},
errors: {
type: Array,
},
helperText: {
type: String
},
placeholder: {
type: String,
},
value: {
required: false,
default: '',
},
loading: {
type: Boolean,
required: false,
default: false,
},
disabled: {
type: Boolean,
required: false,
default: false,
},
autofocus: {
type: Boolean,
required: false,
default: false,
}
},
components: {
FormGroup,
Label,
ErrorText,
HelperText,
IconClipboard,
IconKey,
},
data() {
return {
defaultClasses,
copied: false,
}
},
watch: {
copied() {
let vm = this;
if (this.copied) {
setTimeout(() => {
vm.copied = false;
}, 1250);
}
}
},
methods: {
updateValue(value) {
this.$emit('input', value);
},
},
computed: {},
}
</script>