Go backend (miekg/dns) + Nuxt 3 frontend (Tailwind CSS v4). 8 check categories, 52 checks total: - Overview: @ record, WWW, MX with ASN/provider lookup - Domain Registration: expiry, registrar (RDAP + whois fallback) - Parent Delegation: NS records, glue, consistency - Nameservers: 17 checks (reachability, auth, recursion, TCP/UDP, AXFR, etc.) - SOA: serial consistency, timing values - Mail (MX): 11 checks (CNAME, PTR, public IPs, consistency) - Mail Auth: SPF, DKIM, DMARC - WWW: A record, CNAME Features: - SSE streaming (results appear as each category completes) - SQLite history (modernc.org/sqlite) - Rate limiting, CORS, request logging - Dark mode, responsive design
52 lines
1.9 KiB
Vue
52 lines
1.9 KiB
Vue
<template>
|
|
<form @submit.prevent="onSubmit" class="flex flex-col gap-3 sm:flex-row">
|
|
<div class="relative flex-1">
|
|
<input
|
|
v-model="input"
|
|
type="text"
|
|
placeholder="Enter domain name (e.g., example.com)"
|
|
class="w-full rounded-xl border border-gray-300 bg-white px-4 py-3 text-base shadow-sm placeholder:text-gray-400 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:placeholder:text-gray-500 dark:focus:border-indigo-400 dark:focus:ring-indigo-400/20"
|
|
/>
|
|
</div>
|
|
<button
|
|
type="submit"
|
|
:disabled="!input.trim()"
|
|
class="inline-flex items-center justify-center gap-2 rounded-xl bg-indigo-600 px-6 py-3 text-base font-semibold text-white shadow-sm transition hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-indigo-500 dark:hover:bg-indigo-600"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
</svg>
|
|
Check DNS
|
|
</button>
|
|
</form>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const props = defineProps<{
|
|
initialValue?: string
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
submit: [domain: string]
|
|
}>()
|
|
|
|
const input = ref(props.initialValue || '')
|
|
|
|
function cleanDomain(raw: string): string {
|
|
let domain = raw.trim()
|
|
domain = domain.replace(/^https?:\/\//, '')
|
|
domain = domain.replace(/^www\./, '')
|
|
domain = domain.replace(/\/+$/, '')
|
|
domain = domain.split('/')[0]
|
|
return domain.toLowerCase()
|
|
}
|
|
|
|
function onSubmit() {
|
|
const domain = cleanDomain(input.value)
|
|
if (domain) {
|
|
input.value = domain
|
|
emit('submit', domain)
|
|
}
|
|
}
|
|
</script>
|