226 lines
10 KiB
JavaScript
226 lines
10 KiB
JavaScript
Vue.component('Domain', {
|
|
//language=Vue
|
|
template: `
|
|
<div>
|
|
|
|
<!-- start page title -->
|
|
<tt-page-title :title="window['TT_CONFIG']['PAGE_TITLE']" :path="window['TT_CONFIG']['PATH']"></tt-page-title>
|
|
|
|
<tt-table :fetch-url="window['TT_CONFIG']['DOMAIN_API_URL'] + '?do=getDomains'" :config="domainsTableConfig"
|
|
small ssr ref="table">
|
|
<template v-slot:top-buttons>
|
|
<button type="button" class="btn btn-primary" @click="reloadDomains">
|
|
<template v-if="reloadDomainsLoading">
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
</template>
|
|
<template v-else>
|
|
<i class="fas fa-sync-alt"></i>
|
|
Reload Domains
|
|
</template>
|
|
</button>
|
|
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" v-model="checkDomainInput" style="height: 100%" placeholder="Neue Domain überprüfen">
|
|
<div class="input-group-append">
|
|
<button class="btn btn-primary" @click="checkDomainAvailability">
|
|
<template v-if="checkDomainLoading">
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
</template>
|
|
<template v-else>
|
|
<i class="fas fa-search"></i>
|
|
</template>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- Slot to show DNS records button -->
|
|
<template v-slot:inwxroid="{ row }">
|
|
<button type="button" class="btn btn-primary" @click="showDnsRecordsModal(row.domain)"
|
|
:class="dnsRecordsModalLoading === row.domain ? 'disabled' : ''">
|
|
<template v-if="dnsRecordsModalLoading === row.domain">
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
</template>
|
|
<span v-else>DNS</span>
|
|
</button>
|
|
</template>
|
|
|
|
<!-- Registrant Admin Tech Billing from domainContacts -->
|
|
<template v-slot:registrant="{ row }">
|
|
{{ domainContacts[row.registrant] ? domainContacts[row.registrant]["name"] : '' }}
|
|
</template>
|
|
<template v-slot:admin="{ row }">{{ domainContacts[row.admin] ? domainContacts[row.admin]["name"] : ''}}
|
|
</template>
|
|
<template v-slot:tech="{ row }">{{ domainContacts[row.tech] ? domainContacts[row.tech]["name"] : ''}}
|
|
</template>
|
|
<template v-slot:billing="{ row }">{{ domainContacts[row.billing] ? domainContacts[row.billing]["name"] : ''}}
|
|
</template>
|
|
|
|
</tt-table>
|
|
|
|
<!-- Bootstrap Modal to query and show all DNS records for a domain -->
|
|
<div class="modal show d-block" tabindex="-1" role="dialog" style="background: rgba(0, 0, 0, 0.5);"
|
|
ref="dnsRecordsModal" @click="dnsRecordsModal.domain = null" @keydown.esc="dnsRecordsModal.domain = null"
|
|
v-if="dnsRecordsModal.domain">
|
|
<div class="modal-dialog" role="document" style="max-width: fit-content" @click.stop>
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">DNS Records for {{ dnsRecordsModal.domain ?? '' }}</h5>
|
|
<button type="button" class="close" @click="dnsRecordsModal.domain = null">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<table class="tt-table table-striped table-bordered table-hover table-sm table-condensed">
|
|
<thead>
|
|
<tr>
|
|
<th>Record Class</th>
|
|
<th>Record Type</th>
|
|
<th>Record Host</th>
|
|
<th>Record Value</th>
|
|
<th>Record TTL</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="record in dnsRecordsModal.records">
|
|
<td v-if="record">{{ record.class }}</td>
|
|
<td>{{ record.type }} {{ record.pri ? '(' + record.pri + ')' : '' }}</td>
|
|
<td>{{ record.host }}</td>
|
|
<td>{{ record.value }}</td>
|
|
<td>{{ record.ttl }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-secondary" @click="dnsRecordsModal.domain = null">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
`,
|
|
data() {
|
|
return {
|
|
window: window,
|
|
domainContacts: {},
|
|
reloadDomainsLoading: false,
|
|
dnsRecordsModalLoading: null,
|
|
dnsRecordsModal: {
|
|
domain: null, records: []
|
|
},
|
|
checkDomainInput: '',
|
|
checkDomainResult: null,
|
|
checkDomainLoading: false
|
|
}
|
|
}, created() {
|
|
this.fetchDomainContacts().then()
|
|
}, computed: {
|
|
domainsTableConfig() {
|
|
const base = {
|
|
headers: [{text: "DNS", key: "inwxRoId", filter: false, sortable: false}, {
|
|
text: "Domain",
|
|
key: "domain"
|
|
}, {
|
|
text: "Plesk",
|
|
key: "pleskId",
|
|
filter: 'iconSelect',
|
|
filterOptions: [{value: 1, text: 'Yes', icon: 'fas fa-check text-success'}, {
|
|
value: 0,
|
|
text: 'No',
|
|
icon: 'fas fa-times text-danger'
|
|
}],
|
|
sortable: false
|
|
}, {text: "Created Date", key: "crDate", filter: "date"}, {
|
|
text: "Expiration Date",
|
|
key: "exDate",
|
|
filter: "date"
|
|
}, {text: "Renewal Date", key: "reDate", filter: "date"}, {
|
|
text: "Updated Date",
|
|
key: "upDate",
|
|
filter: "date"
|
|
}, {
|
|
text: "Transfer Lock",
|
|
key: "transferLock",
|
|
filter: 'iconSelect',
|
|
filterOptions: [{value: 1, text: 'Locked', icon: 'fas fa-lock text-danger'}, {
|
|
value: 0,
|
|
text: 'Unlocked',
|
|
icon: 'fas fa-unlock text-success'
|
|
}]
|
|
}, {text: "Authorization Code", key: "authCode", sortable: false}, {
|
|
text: "Registrant ID",
|
|
key: "registrant",
|
|
sortable: false
|
|
}, {text: "Admin ID", key: "admin", sortable: false}, {
|
|
text: "Tech ID",
|
|
key: "tech",
|
|
sortable: false
|
|
}, {text: "Billing ID", key: "billing", sortable: false}, {text: "Name Servers", key: "ns"}],
|
|
tableHeader: 'Domains',
|
|
key: 'Domain'
|
|
}
|
|
|
|
const domainContactsSorted = Object.entries(this.domainContacts).sort(([, a], [, b]) => a.name.localeCompare(b.name))
|
|
const domainContactsFilterOptions = domainContactsSorted.map(([, contact]) => {
|
|
return {text: contact.name, value: contact.inwxRoId}
|
|
})
|
|
|
|
// for registrant admin tech billing set filter to select with domainContacts if domainContacts is not empty
|
|
if (Object.keys(this.domainContacts).length > 0) {
|
|
base.headers = base.headers.map(header => {
|
|
if (['registrant', 'admin', 'tech', 'billing'].includes(header.key)) {
|
|
header.filter = 'select'
|
|
header.filterOptions = domainContactsFilterOptions
|
|
}
|
|
return header
|
|
})
|
|
}
|
|
return base
|
|
}
|
|
}, methods: {
|
|
async showDnsRecordsModal(domain) {
|
|
this.dnsRecordsModalLoading = domain
|
|
this.dnsRecordsModal = {
|
|
domain: null, records: []
|
|
}
|
|
const response = await axios.get(window['TT_CONFIG']['DOMAIN_API_URL'] + '?do=getDnsRecords&domain=' + domain)
|
|
this.dnsRecordsModal.domain = domain
|
|
this.dnsRecordsModal.records = response.data.map(record => {
|
|
if (typeof record.entries === 'object') {
|
|
record.value = record.entries[0]
|
|
} else {
|
|
record.value = record.target || record.txt || record.ip
|
|
}
|
|
if (record.type === 'SOA') {
|
|
record.value = record.mname + ' ' + record.rname + ' ' + record.serial + ' ' + record.refresh + ' ' + record.retry + ' ' + record.expire
|
|
|
|
}
|
|
return record
|
|
})
|
|
this.dnsRecordsModalLoading = null
|
|
this.$nextTick(() => {
|
|
this.$refs.dnsRecordsModal.focus()
|
|
})
|
|
}, async fetchDomainContacts() {
|
|
const response = await axios.get(window['TT_CONFIG']['DOMAIN_API_URL'] + '?do=getDomainContacts')
|
|
this.domainContacts = response.data
|
|
}, async reloadDomains() {
|
|
this.reloadDomainsLoading = true
|
|
const response = await axios.get(window['TT_CONFIG']['DOMAIN_API_URL'] + '?do=importAllDomains')
|
|
window.notify('success', response.data["importMessages"].join('<br>'))
|
|
await Promise.all([this.fetchDomainContacts(), this.$refs.table.fetchData(this.$refs.table.pagination.page)])
|
|
this.reloadDomainsLoading = false
|
|
}, //TODO: make this cleaner
|
|
async checkDomainAvailability() {
|
|
this.checkDomainLoading = true
|
|
const response = await axios.get(window['TT_CONFIG']['DOMAIN_API_URL'] + '?do=checkDomain&domain=' + this.checkDomainInput)
|
|
const priceInformation = response.data.price.domain[this.checkDomainInput]
|
|
window.notify(response.data.status === 'free' ? 'success' : 'error', `Domain ist ${response.data.status === 'free' ? 'verfügbar. Registrieren um' : 'nicht frei. Transfer um'} ${priceInformation.price}${priceInformation.currency}/${priceInformation.period === '1Y' ? 'Jahr' : priceInformation.period}`)
|
|
this.checkDomainLoading = false
|
|
}
|
|
}
|
|
|
|
})
|