domain.go

74 lines
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
package internal

import (
	"net"

	"congo.gg/dev/models"
	"congo.gg/pkg/router"
)

// SetupDomain registers a domain as a system route.
// System routes tell autocert to issue TLS certs and identify
// the app's own domain. Safe to call multiple times.
func SetupDomain(domain string) error {
	if domain == "" {
		return nil
	}

	existing, _ := models.Domains.First("WHERE Host = ?", domain)
	if existing != nil {
		return nil
	}

	_, err := models.Domains.Insert(&models.Domain{
		Host:   domain,
		Target: "congo-dev",
		Port:   5000,
		Active: true,
		System: true,
	})
	if err != nil {
		return err
	}
	// Add to cert manager immediately (no restart needed)
	router.AllowDomainUnchecked(domain)
	return nil
}

// SystemDomain returns the primary system domain, if one exists.
func SystemDomain() string {
	d, _ := models.Domains.First("WHERE System = 1 AND Active = 1")
	if d != nil {
		return d.Host
	}
	return ""
}

// DomainDNSStatus describes whether a domain resolves to this server.
type DomainDNSStatus struct {
	Resolves   bool   // Domain resolves in DNS
	PointsHere bool   // Resolves to this server's IP
	ResolvedIP string // What IP it resolved to
	ServerIP   string // This server's IP
}

// CheckDomainDNS verifies if a domain points to this server's IP.
func CheckDomainDNS(host string) *DomainDNSStatus {
	status := &DomainDNSStatus{}
	status.ServerIP = router.ServerIP()

	ips, err := net.LookupHost(host)
	if err != nil || len(ips) == 0 {
		return status
	}

	status.Resolves = true
	status.ResolvedIP = ips[0]
	for _, ip := range ips {
		if ip == status.ServerIP {
			status.PointsHere = true
			break
		}
	}
	return status
}