domainverifier

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2023 License: BSD-3-Clause Imports: 15 Imported by: 0

README

domainverifier

CI Go Report Card Go Reference GitHub go.mod Go version

domainverifier is a Go package that provides a fast and simple way to verify domain name ownership. It also includes a generator module, which makes it easier for developers who are new to DNS verification, to quickly set up and integrate the verification process into their applications.

The package offers support for 5 different verification methods: HTML Meta Tag, JSON File Upload, XML File Upload, DNS TXT record and DNS CNAME record.

Installation

To get the package use the standard:

go get -u github.com/egbakou/domainverifier

Using Go modules is recommended.

Usage

This section assumes prior knowledge of domain name ownership verification. If not, please review the example code for each verification method, which include the process of instructions generation.

🚀 Html Meta Tag method

HTML Meta Tag is an element that provide metadata about a web page. It is placed in the head section of an HTML document and provides information about the page to search engines, web browsers, and other services.

This method requires the ability for the users to edit the HTML source code of their site's homepage.

💻 Generation

The generator module contains two functions for generating HTML Meta tags to verify ownership of a specific domain name.

⤵️func GenerateHtmlMetaFromConfig(config *config.HmlMetaTagGenerator, useInternalCode bool) (*HtmlMetaInstruction, error)

config := &config.HmlMetaTagGenerator{
	TagName: "example-tag",
	Code:    "external-code", // a unique random string, optional if useInternalCode is true
}

// If useInternalCode is set to true, config.Code will be automatically filled with an internal K-Sortable Globally Unique ID
instruction, err := domainverifier.GenerateHtmlMetaFromConfig(config, false)

if err == nil {
	fmt.Println("Html Code", instruction.Code)
	// Output: <meta name="example-tag" content="external-code" />
	fmt.Println("Indication to provide to the user", instruction.Action)
	// Output:
	// Copy and paste the <meta> tag into your site's home page.
	// It should go in the <head> section, before the first <body> section.
	// <meta name="example-tag" content="external-code" />
	// * To stay verified, don't remove the meta tag even after verification succeeds.
}

💡 Ensure that you have stored the Tag Name and code in the database as they will be necessary parameters for the subsequent ownership verification process.

⤵️func GenerateHtmlMeta(appName string, sanitizeAppName bool) (*HtmlMetaInstruction, error)

This function offers a straightforward approach to generating instructions for the HTML meta tag method.

The appName serves as TagName appended by -site-verification. If sanitizeAppName is set to true, non-alphanumeric characters will be removed from the appName.

instruction, err := domainverifier.GenerateHtmlMeta("your app name", true)

if err == nil {
	fmt.Println("Html Code:", instruction.Code)
	// Output: 
	// <meta name="yourappname-site-verification" content="random K-Sortable unique code" />
	fmt.Println("Indication to provide to the user:", instruction.Action)
	// Output:
	// Copy and paste the <meta> tag into your site's home page.
	// It should go in the <head> section, before the first <body> section.
	// <meta name="yourappname-site-verification" content="random K-Sortable unique code" />
	// * To stay verified, don't remove the meta tag even after verification succeeds.
}

🔎 Verification

The verification process is quick and straightforward. It requires:

  • The domain name for which you’ve generated the verification instructions
  • The Html Meta Tag Name and it value(Code) you have stored somewhere
isVerified, err := domainverifier.CheckHtmlMetaTag("the-domain-to-verify.com",
		"tag name",
		"verification-code")

fmt.Println("Is ownership verified:", isVerified)
🚀 JSON file upload method

In the JSON method, you need to create a JSON file that contains a specific structure, including a key-value pair that proves ownership of the domain. Users then upload the JSON file to their website's root directory.

After the JSON file has been uploaded, the ownership verification service can access it and verify its contents to confirm that the user does indeed own the domain.

💻 Generation

⤵️ GenerateJsonFromConfig(config *config.JsonGenerator, useInternalCode bool) (*FileInstruction, error)

config := &config.JsonGenerator{
	FileName:  "example.json",
	Attribute: "code",
	Code:      "external-code", // optional if useInternalCode is true
},

// If useInternalCode is set to true, config.Code will be automatically filled with an internal K-Sortable Globally Unique ID
instruction, err := domainverifier.GenerateJsonFromConfig(config, false)

if err == nil {
	fmt.Println("FileName :", instruction.FileName)
	// Output: 
	// example.json
	fmt.Println("FileContent:", instruction.FileContent)
	// Output: 
	// {"code": "external-code"}
	fmt.Println("Indication to provide to the user", instruction.Action)
	// Output:
	// Create a JSON file named example.json with the content
	// {"code": "external-code"}
	// and upload it to the root of your site.
}

💡 It is important to store FileName, Attribute, and Code in the database, as this data will be essential for verifying ownership later.

⤵️ func GenerateJson(appName string) (*FileInstruction, error)

The appName serves as Attribute appended by _site_verification.

instruction, err := domainverifier.GenerateJson("your app name")

if err == nil {
	fmt.Println("FileName :", instruction.FileName)
	// Output: 
	// yourappname-site_verification.json
	fmt.Println("FileContent:", instruction.FileContent)
	// Output: 
	// {"yourappname_site_verification": "random K-Sortable unique code"}
	fmt.Println("Indication to provide to the user", instruction.Action)
	// Output:
	// Create a JSON file named yourappname-site_verification.json with the content
	// {"yourappname_site_verification": "random K-Sortable unique code"}
	// and upload it to the root of your site.
}

🔎 Verification

Requirements:

  • The domain name for which you have generated the verification instructions
  • The JSON file name
  • An object of type struct that matches the content of the JSON file.

As an example, suppose the domain name to be verified is the-domain-to-verify.com, the JSON file is named example.json, and the contents of the file are {"code": "verification-code"}. To perform ownership verification, you can use the following code snippet. Keep in mind that the file at http://the-domain-to-verify.com/example.json or https://the-domain-to-verify.com/example.json must be accessible.

In that case, the following code snippet demonstrates how to perform ownership verification.

type ownershipVerification struct {
	Code string json:"code"
}

expectedValue := ownershipVerification{Code: "verification-code"}

isVerified, err := domainverifier.CheckJsonFile("the-domain-to-verify.com",
		"example.json",
		expectedValue)

fmt.Println("Is ownership verified:", isVerified)
🚀 XML file upload method

This approach is similar to the JSON method. There are two functions you can use to provide verification instructions to users.

⤵️ func GenerateXmlFromConfig(config *config.XmlGenerator, useInternalCode bool) (*FileInstruction, error)

config: &config.XmlGenerator{
	FileName: "example.xml",
	RootName: "example-root",
	Code:     "internal-code",
}

// If useInternalCode is set to true, config.Code will be automatically filled with an internal K-Sortable Globally Unique ID
instruction, err := GenerateXmlFromConfig(config, false)

if err == nil {
	fmt.Println("FileName :", instruction.FileName)
	// Output: 
	// example.xml
	fmt.Println("FileContent:", instruction.FileContent)
	// Output: 
	// <example-root><code>internal-code</code></example-root>
	fmt.Println("Indication to provide to the user", instruction.Action)
	// Output:
	// Create an XML file named example.xml with the content:
	// <example-root><code>internal-code</code></example-root>
	// and upload it to the root of your site.
}

💡 FileName, RootName, and Code must be stored in database.

⤵️ func GenerateXml(appName string, sanitizeAppName bool) (*FileInstruction, error)

The appName serves as FileName appended by SiteAuth.xml.

// We advise setting the sanitizeAppName parameter to true
instruction, err := GenerateXml("your app name", true)

if err == nil {
	fmt.Println("FileName :", instruction.FileName)
	// Output: 
	// YourappnameSiteAuth.xml
	fmt.Println("FileContent:", instruction.FileContent)
	// Output: 
	// <verification><code>random K-Sortable unique code</code></verification>
	fmt.Println("Indication to provide to the user", instruction.Action)
	// Output:
	// Create an XML file named YourappnameSiteAuth.xml with the content:
	// <verification><code>random K-Sortable unique code</code></verificationt>
	// and upload it to the root of your site.
}

🔎 Verification

Requirements:

  • The domain name for which you have generated the verification instructions
  • The XML file name
  • An object of type struct that matches the content of the XML file.
type ownershipVerification struct {
    XMLName struct{} `xml:"verification"`
	Code string `xml:"code"`
}

expectedValue := ownershipVerification{Code: "verification-code"}

isVerified, err := domainverifier.CheckXmlFile("the-domain-to-verify.com",
		"example.xml",
		expectedValue)

fmt.Println("Is ownership verified:", isVerified)
🚀 DNS TXT record method

With this method, user needs to add a specific TXT record to the DNS configuration of their domain. The TXT record contains a unique value that proves ownership of the domain.

💻 Generation

⤵️ func GenerateTxtRecordFromConfig(config *config.TxtRecordGenerator, useInternalCode bool) (*DnsRecordInstruction, error)

This function allows you to generate instructions for the DNS TXT record method.

config: &config.TxtRecordGenerator{
	HostName:             "@", // or domain.com for example
	RecordAttribute:      "myapp",
	RecordAttributeValue: "random-code",
},

// If useInternalCode is set to true, cf.code will be automatically filled with an internal K-Sortable Globally Unique ID
instruction, err := domainverifier.GenerateTxtFromConfig(config, false)

if err == nil {
	fmt.Println("HostName:", instruction.HostName)
	// Output:
	// @ or domain.com
	fmt.Println("Record:", instruction.Record)
	// Output:
	// myapp=random-code
	fmt.Println("Indications to provide to the user", instruction.Action)
	// Output:
	// Create a TXT record with the name @ and the content myapp=random-code
}

💡 Remember to store the config object somewhere.

⤵️ func GenerateTxtRecord(appName string) (*DnsRecordInstruction, error)

The appName serves as RecordAttribute appended by -site-verification

instruction, err := domainverifier.GenerateTxtRecord("your app name")

if err == nil {
	fmt.Println("HostName:", instruction.HostName)
	// Output:
	// @
	fmt.Println("Record:", instruction.Record)
	// Output:
	// yourappname-site-verification=random K-Sortable unique code
	fmt.Println("Indications to provide to the user", instruction.Action)
	// Output:
	// Create a TXT record with the name @ and the content yourappname-site-verification=random K-Sortable unique code
}

🔎 Verification

Requirements:

  • The DNS server to use, if empty Cloudflare DNS will be used.
  • The domain name for which you have generated the verification instructions
  • The Host name
  • The record content
isVerified, err := domainverifier.CheckTxtRecord(dnsresolver.GooglePublicDNS, "the-domain-to-verify.com", "@", "yapp=random-code")

fmt.Println("Is ownership verified:", isVerified)
🚀 DNS CNAME record method

💻 Generation

⤵️ func GenerateCnameRecordFromConfig(config *config.CnameRecordGenerator) (*DnsRecordInstruction, error)

config: &config.CnameRecordGenerator{
	RecordName:   "random-code",
	RecordTarget:  "verify.example.com",
},

instruction, err := domainverifier.GenerateCnameFromConfig(config)

if err == nil {
	fmt.Println("HostName:", instruction.HostName)
	// Output:
	// random-code
	fmt.Println("Record:", instruction.Record)
	// Output:
	// verify.example.com
	fmt.Println("Indications to provide to the user", instruction.Action)
	// Output:
	// Add CNAME (alias) record with name random-code and value verify.example.com.
}

💡 Ensure to store the DNS CNAME record information generated, including the Record Name and Record Target.

🔍 Verification

Requirements:

  • The DNS server to use, if empty Cloudflare DNS will be used.
  • The domain name for which you have generated the verification instructions
  • The record name
  • The target value
isVerified, err := domainverifier.CheckCnameRecord(dnsresolver.GooglePublicDNS, "the-domain-to-verify.com", "random-code", "verify.example.com")

fmt.Println("Is ownership verified:", isVerified)

Utility functions

In addition to its main features, domainverifier provides some helper functions that can be used.

  • domainverifier.IsSecure(domain string, timeout time.Duration) returns a Boolean value indicating whether the specified domain supports a secure connection over HTTPS or not.
  • domainverifier.IsValidDomainName(domain string) checks if a string is a valid domain name.

Contributions

We're always looking for contributions to make this project even better! If you're interested in helping out, please take a look at our open issues, or create a new one if you have an idea for a feature or bug fix. We appreciate any and all help, so don't hesitate to reach out if you want to get involved!

Documentation

Index

Constants

This section is empty.

Variables

View Source
var InvalidAppNameError = errors.New("app name cannot be empty")

InvalidAppNameError indicates that the app name is invalid.

View Source
var InvalidDomainError = errors.New("invalid domain name")

InvalidDomainError indicates that the domain name is invalid

View Source
var InvalidResponseError = errors.New("invalid response status code returned by the server")

InvalidResponseError indicates that the response is invalid

Functions

func CheckCnameRecord

func CheckCnameRecord(dnsResolver, domain, recordName, targetValue string) (bool, error)

CheckCnameRecord checks if the domain has a DNS CNAME record with the specified values to verify ownership of the domain

Parameters:

  • dnsResolver: the DNS server to use
  • domain: the domain name to verify the ownership
  • recordName: the name of the DNS CNAME record to check
  • targetValue: the value of recordName

Returns:

  • true if the ownership of the domain is verified
  • error if any

Example:

dnsResolver = dnsresolver.CloudflareDNS
domain := "website.com"
recordName := "1234567890"
targetValue := "verify.myapp.com"
verified, err := domainverify.CheckDnsCnameRecord(dnsResolver, domain, recordName, targetValue)

func CheckHtmlMetaTag

func CheckHtmlMetaTag(domain, metaTagName, metaTagContent string) (bool, error)

CheckHtmlMetaTag checks if the html meta tag exists and has the expected value

Parameters:

domain: the domain name to check
metaTagName: the name of the meta tag to check
metaTagContent: the expected value of the meta tag

Returns:

  • true if the ownership of the domain is verified
  • error if any

func CheckJsonFile

func CheckJsonFile(domain, fileName string, expectedValue interface{}) (bool, error)

CheckJsonFile checks if the json file exists and has the expected content to verify ownership of the domain

Parameters:

  • domain: the domain name to check
  • fileName: the name of the json file to check
  • expectedValue: the expected content

Returns:

  • true if the ownership of the domain is verified
  • error if any

Example:

type OwnershipVerification struct {
	Code string `json:"myapp_site_verification"`
}
data := OwnershipVerification{Code: "1234567890"}
domain := "website.com"
fileName := "myapp-site-verification.json" // excepted file content: {"myapp_site_verification": "1234567890"}
verified, err := domainverify.CheckJsonFile(domain, fileName, data)

func CheckTxtRecord

func CheckTxtRecord(dnsResolver, domain, hostName, recordContent string) (bool, error)

CheckTxtRecord checks if the domain has a DNS TXT record with the specified values to verify ownership of the domain

Parameters:

  • dnsResolver: the DNS server to use
  • domain: the domain name to verify
  • hostName: the TXT record name
  • recordContent: the content of the TXT record

Returns:

  • true if the ownership of the domain is verified
  • error if any

Example:

dnsResolver = dnsresolver.CloudflareDNS
domain := "website.com"
hostName := "@"
recordContent := "myapp-site-verification=1234567890"
verified, err := domainverify.CheckDnsTxtRecord(dnsServer, domain, hostName, recordContent)

func CheckXmlFile

func CheckXmlFile(domain, fileName string, expectedValue interface{}) (bool, error)

CheckXmlFile checks if the xml file exists and has the expected content to verify ownership of the domain

Parameters:

  • domain: the domain name to check
  • fileName: the name of the xml file to check
  • expectedValue: the expected content

Returns:

  • true if the ownership of the domain is verified
  • error if any

Example:

type OwnershipVerification struct {
    XMLName struct{} `xml:"verification"`
	Code string `xml:"code" json:"myapp_site_verification"`
}
data := OwnershipVerification{Code: "1234567890"}
domain := "website.com"
fileName := "myappSiteAuth.xml" // excepted file content: <verification><code>1234567890</code></verification>
verified, err := domainverify.CheckXmlFile(domain, fileName, data)

func IsSecure

func IsSecure(domain string, timeout time.Duration) (bool, error)

IsSecure returns a boolean value indicating whether the specified domain supports a secure connection over HTTPS or not. If the domain is not reachable, an error is returned.

func IsValidDomainName

func IsValidDomainName(domain string) bool

IsValidDomainName checks if a string is a valid domain name.

Types

type DnsRecordInstruction

type DnsRecordInstruction struct {
	HostName string
	Record   string
	Action   string
}

DnsRecordInstruction is the CNAME or TXT record instruction.

func GenerateCnameRecordFromConfig

func GenerateCnameRecordFromConfig(config *config.CnameRecordGenerator) (*DnsRecordInstruction, error)

GenerateCnameRecordFromConfig generates the CNAME verification method instructions. It uses the provided config.CnameGenerator to generate the instructions.

func GenerateTxtRecord

func GenerateTxtRecord(appName string) (*DnsRecordInstruction, error)

GenerateTxtRecord generates the TXT verification method instructions. appName is the name of the app that is requesting the verification (e.g. bing, google, etc.). It will be used as prefix of the record attribute.

func GenerateTxtRecordFromConfig

func GenerateTxtRecordFromConfig(config *config.TxtRecordGenerator, useInternalCode bool) (*DnsRecordInstruction, error)

GenerateTxtRecordFromConfig generates the TXT verification method instructions. It uses the provided config.TxtGenerator to generate the instructions. If useInternalCode is true, internal K-Sortable Globally Unique ID will be generated for the record attribute value. Otherwise, the RecordAttribute in the config.TxtGenerator will be used.

type FileInstruction

type FileInstruction struct {
	FileName    string
	FileContent string
	Action      string
}

FileInstruction is the JSON or XML file instruction.

func GenerateJson

func GenerateJson(appName string) (*FileInstruction, error)

GenerateJson generates the JSON verification method instructions. appName is the name of the app that is requesting the verification (e.g. google, bing, etc.). It will be used as prefix of the file name and the attribute name. Note that the appName will be sanitized to non-alphanumeric characters.

func GenerateJsonFromConfig

func GenerateJsonFromConfig(config *config.JsonGenerator, useInternalCode bool) (*FileInstruction, error)

GenerateJsonFromConfig generates the JSON verification method instructions. It uses the provided config.JsonGenerator to generate the instructions. If useInternalCode is true, internal K-Sortable Globally Unique ID will be generated. Otherwise, the code in the config.JsonGenerator will be used.

func GenerateXml

func GenerateXml(appName string, sanitizeAppName bool) (*FileInstruction, error)

GenerateXml generates the XML verification method instructions. appName is the name of the app that is requesting the verification (e.g. bing, google, etc.). It will be used as prefix of the file name. Note that the appName will be sanitized to non-alphanumeric characters.

func GenerateXmlFromConfig

func GenerateXmlFromConfig(config *config.XmlGenerator, useInternalCode bool) (*FileInstruction, error)

GenerateXmlFromConfig generates the XML verification method instructions. It uses the provided config.XmlGenerator to generate the instructions. If useInternalCode is true, internal K-Sortable Globally Unique ID will be generated. Otherwise, the code in the config.XmlGenerator will be used.

type HtmlMetaInstruction

type HtmlMetaInstruction struct {
	Code   string
	Action string
}

HtmlMetaInstruction is the Html meta tag instruction.

func GenerateHtmlMeta

func GenerateHtmlMeta(appName string, sanitizeAppName bool) (*HtmlMetaInstruction, error)

GenerateHtmlMeta generates the HTML meta tag verification method instructions. appName is the name of the app that is requesting the verification (e.g. msvalidate.01, mysuperapp, etc.). It will be used as the name of the meta tag. Note that the appName will be sanitized to non-alphanumeric characters.

func GenerateHtmlMetaFromConfig

func GenerateHtmlMetaFromConfig(config *config.HmlMetaTagGenerator, useInternalCode bool) (*HtmlMetaInstruction, error)

GenerateHtmlMetaFromConfig generates the HTML meta tag verification method instructions. It uses the provided config.HmlMetaTagGenerator to generate the instructions. If useInternalCode is true, internal K-Sortable Globally Unique ID will be generated. Otherwise, the code in the config.HmlMetaTagGenerator will be used.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL