happyDomain/ui/src/views/hToolsClient.vue

350 lines
13 KiB
Vue

<!--
Copyright or © or Copr. happyDNS (2020)
contact@happydomain.org
This software is a computer program whose purpose is to provide a modern
interface to interact with DNS systems.
This software is governed by the CeCILL license under French law and abiding
by the rules of distribution of free software. You can use, modify and/or
redistribute the software under the terms of the CeCILL license as
circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
As a counterpart to the access to the source code and rights to copy, modify
and redistribute granted by the license, users are provided only with a
limited warranty and the software's author, the holder of the economic
rights, and the successive licensors have only limited liability.
In this respect, the user's attention is drawn to the risks associated with
loading, using, modifying and/or developing or reproducing the software by
the user in light of its specific status of free software, that may mean
that it is complicated to manipulate, and that also therefore means that it
is reserved for developers and experienced professionals having in-depth
computer knowledge. Users are therefore encouraged to load and test the
software's suitability as regards their requirements in conditions enabling
the security of their systems and/or data to be ensured and, more generally,
to use and operate it in the same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms.
-->
<template>
<b-container class="d-flex flex-column" :fluid="responses?true:false">
<b-row class="flex-grow-1">
<b-col :offset-md="responses?0:2" :md="responses?4:8" :class="(responses?'bg-light ':'') + 'pt-4 pb-5 sticky-top'">
<h1 class="text-center mb-3">
{{ $t('menu.dns-resolver') }}
</h1>
<form class="pt-3 pb-5" @submit.stop.prevent="submitRequest">
<b-form-group
id="input-domain"
:label="$t('common.domain')"
label-for="domain"
>
<template slot="description">
<i18n path="resolver.domain-description">
<router-link to="/resolver/wikipedia.org" class="text-monospaced">
wikipedia.org
</router-link>
</i18n>
</template>
<b-form-input
id="domain"
v-model="form.domain"
list="my-domains"
required
placeholder="happydomain.org"
/>
<datalist v-if="sortedDomains" id="my-domains">
<option v-for="dn in sortedDomains" :key="dn.id">
{{ dn.domain }}
</option>
</datalist>
</b-form-group>
<div class="text-center mb-3">
<b-button v-b-toggle.resolver-advanced-settings variant="secondary">
{{ $t('resolver.advanced') }}
</b-button>
</div>
<b-collapse id="resolver-advanced-settings">
<b-form-group
id="input-type"
:label="$t('common.field')"
label-for="type"
>
<template slot="description">
<i18n path="resolver.field-description">
<a href="//help.happydomain.org/tools/resolver" target="_blank">{{ $t('resolver.field-description-more-info') }}</a>
</i18n>
</template>
<b-form-select
id="type"
v-model="form.type"
required
:options="existing_types"
/>
</b-form-group>
<b-form-group
id="input-resolver"
:label="$t('common.resolver')"
label-for="resolver"
:description="$t('resolver.resolver-description')"
>
<b-form-select
id="resolver"
v-model="form.resolver"
required
>
<b-form-select-option-group
v-for="(group, gname) in existing_resolvers"
:key="gname"
:label="gname"
:options="group"
/>
<b-form-select-option value="custom">
{{ $t('resolver.custom') }}
</b-form-select-option>
</b-form-select>
</b-form-group>
<b-form-group
v-show="form.resolver === 'custom'"
id="input-custom-resolver"
:label="$t('resolver.custom')"
label-for="custom-resolver"
:description="$t('resolver.custom-description')"
>
<b-form-input
id="custom-resolver"
v-model="form.custom"
:required="form.resolver === 'custom'"
placeholder="127.0.0.1"
/>
</b-form-group>
<b-form-checkbox
id="showDNSSEC"
v-model="showDNSSEC"
name="showDNSSEC"
class="mb-3"
>
{{ $t('resolver.showDNSSEC') }}
</b-form-checkbox>
</b-collapse>
<div class="ml-3 mr-3">
<b-button class="float-right" type="submit" variant="primary" :disabled="request_pending">
<b-spinner v-if="request_pending" :label="$t('common.spinning')" small />
{{ $t('common.run') }}
</b-button>
</div>
</form>
</b-col>
<b-col v-if="responses === 'no-answer'" md="8" class="pt-2">
<h3>{{ $tc('common.records', 0, { type: question.type }) }}</h3>
</b-col>
<b-col v-else-if="responses" md="8" class="pt-2">
<div v-for="(rrs,type) in responseByType" :key="type">
<h3>{{ $tc('common.records', rrs.length, { type: $options.filters.nsrrtype(type) }) }}</h3>
<table class="table table-hover table-sm">
<thead>
<h-record-head :rrtype="type" />
</thead>
<tbody>
<h-record v-for="(rr,index) in rrs" :key="index" :record="rr" />
</tbody>
</table>
</div>
</b-col>
</b-row>
</b-container>
</template>
<script>
import axios from 'axios'
import { mapGetters } from 'vuex'
export default {
components: {
hRecord: () => import('@/components/hRecord'),
hRecordHead: () => import('@/components/hRecordHead')
},
data: function () {
return {
request_pending: false,
existing_types: ['ANY', 'A', 'AAAA', 'NS', 'SRV', 'MX', 'TXT', 'SOA'],
existing_resolvers: {
Unfiltered:
[
{ value: 'local', text: 'Local resolver' },
{ value: '1.1.1.1', text: 'Cloudflare DNS resolver' },
{ value: '4.2.2.1', text: 'Level3 resolver' },
{ value: '8.8.8.8', text: 'Google Public DNS resolver' },
{ value: '9.9.9.10', text: 'Quad9 DNS resolver without security blocklist' },
{ value: '64.6.64.6', text: 'Verisign DNS resolver' },
{ value: '74.82.42.42', text: 'Hurricane Electric DNS resolver' },
{ value: '208.67.222.222', text: 'OpenDNS resolver' },
{ value: '8.26.56.26', text: 'Comodo Secure DNS resolver' },
{ value: '199.85.126.10', text: 'Norton ConnectSafe DNS resolver' },
{ value: '198.54.117.10', text: 'SafeServe DNS resolver' },
{ value: '84.200.69.80', text: 'DNS.WATCH resolver' },
{ value: '185.121.177.177', text: 'OpenNIC DNS resolver' },
{ value: '37.235.1.174', text: 'FreeDNS resolver' },
{ value: '80.80.80.80', text: 'Freenom World DNS resolver' },
{ value: '216.131.65.63', text: 'StrongDNS resolver' },
{ value: '94.140.14.140', text: 'AdGuard non-filtering DNS resolver' },
{ value: '91.239.100.100', text: 'Uncensored DNS resolver' },
{ value: '216.146.35.35', text: 'Dyn DNS resolver' },
{ value: '77.88.8.8', text: 'Yandex.DNS resolver' },
{ value: '129.250.35.250', text: 'NTT DNS resolver' },
{ value: '223.5.5.5', text: 'AliDNS resolver' },
{ value: '1.2.4.8', text: 'CNNIC SDNS resolver' },
{ value: '119.29.29.29', text: 'DNSPod resolver' },
{ value: '114.215.126.16', text: 'oneDNS resolver' },
{ value: '124.251.124.251', text: 'cloudxns resolver' },
{ value: '114.114.114.114', text: 'Baidu DNS resolver' },
{ value: '156.154.70.1', text: 'DNS Advantage resolver' },
{ value: '87.118.111.215', text: 'FoolDNS resolver' },
{ value: '101.101.101.101', text: 'Quad 101 DNS resolver' },
{ value: '114.114.114.114', text: '114DNS resolver' },
{ value: '168.95.1.1', text: 'HiNet DNS resolver' },
{ value: '80.67.169.12', text: 'French Data Network DNS resolver' },
{ value: '81.218.119.11', text: 'GreenTeamDNS resolver' },
{ value: '208.76.50.50', text: 'SmartViper DNS resolver' },
{ value: '23.253.163.53', text: 'Alternate DNS resolver' },
{ value: '109.69.8.51', text: 'puntCAT DNS resolver' },
{ value: '156.154.70.1', text: 'Neustar DNS resolver' },
{ value: '101.226.4.6', text: 'DNSpai resolver' }
// Your open resolver here? Don't hesitate to contribute to the project!
],
Filtered: [
{ value: '1.1.1.2', text: 'Cloudflare Malware Blocking Only DNS resolver' },
{ value: '1.1.1.3', text: 'Cloudflare Malware and Adult Content Blocking Only DNS resolver' },
{ value: '9.9.9.9', text: 'Quad9 DNS resolver' },
{ value: '94.140.14.14', text: 'AdGuard default DNS resolver' },
{ value: '94.140.14.15', text: 'AdGuard family protection DNS resolver' },
{ value: '77.88.8.2', text: 'Yandex.DNS Safe resolver' },
{ value: '77.88.8.3', text: 'Yandex.DNS Family resolver' },
{ value: '156.154.70.2', text: 'DNS Advantage Threat Protection resolver' },
{ value: '156.154.70.3', text: 'DNS Advantage Family Secure resolver' },
{ value: '156.154.70.4', text: 'DNS Advantage Business Secure resolver' },
{ value: '185.228.168.168', text: 'CleanBrowsing Family Filter DNS resolver' },
{ value: '185.228.168.10', text: 'CleanBrowsing Adult Filter DNS resolver' }
// Your open resolver here? Don't hesitate to contribute to the project!
]
},
form: {
resolver: 'local',
type: 'ANY'
},
question: null,
responses: null,
showDNSSEC: false
}
},
computed: {
responseByType () {
const ret = {}
for (const i in this.filteredResponses) {
if (!ret[this.filteredResponses[i].Hdr.Rrtype]) {
ret[this.filteredResponses[i].Hdr.Rrtype] = []
}
ret[this.filteredResponses[i].Hdr.Rrtype].push(this.filteredResponses[i])
}
return ret
},
filteredResponses () {
if (!this.responses) {
return []
}
if (this.showDNSSEC) {
return this.responses
} else {
return this.responses.filter(rr => (rr.Hdr.Rrtype !== 46 && rr.Hdr.Rrtype !== 47 && rr.Hdr.Rrtype !== 50))
}
},
...mapGetters('domains', ['sortedDomains']),
...mapGetters('user', ['user_isLogged'])
},
watch: {
user_isLogged: function (isLogged) {
if (isLogged) {
this.$store.dispatch('domains/getAllMyDomains')
}
},
$route (n) {
if (n.params.domain && (!this.response || n.params.domain !== this.form.domain)) {
this.form.domain = n.params.domain
this.submitRequest()
} else if (!n.params.domain && this.responses) {
this.responses = null
}
}
},
mounted () {
if (this.user_isLogged) {
this.$store.dispatch('domains/getAllMyDomains')
}
if (this.$route.params.domain) {
this.form.domain = this.$route.params.domain
this.submitRequest()
}
},
methods: {
submitRequest () {
this.request_pending = true
axios
.post('/api/resolver', this.form)
.then(
(response) => {
this.question = Object.assign({}, this.form)
if (response.data.Answer) {
this.responses = response.data.Answer
} else {
this.responses = 'no-answer'
}
this.request_pending = false
},
(error) => {
this.$bvToast.toast(
error.response.data.errmsg, {
title: this.$t('errors.resolve'),
autoHideDelay: 5000,
variant: 'danger',
toaster: 'b-toaster-content-right'
}
)
this.request_pending = false
})
if (this.$route.params.domain !== this.form.domain) {
this.$router.push('/resolver/' + encodeURIComponent(this.form.domain))
}
}
}
}
</script>
<style>
.form-group label {
font-weight: bold;
}
</style>