/*
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for
* more information.
*/
package db
import (
"errors"
"git.src.quest/~skye/felu-ddns/internal/util"
"github.com/oklog/ulid/v2"
)
type DomainOwner struct {
ID string
Email string
}
type Domain struct {
Id string
ApiKey string
Domain string
A string
Owner DomainOwner
}
func FetchDomainsForUser(userId string) ([]Domain, error) {
rows, err := DBConn.Query(`SELECT id, apikey, ddns_domain, a_record
FROM domains WHERE owner = $1`, userId)
if err != nil {
return nil, err
}
defer rows.Close()
var domains []Domain
for rows.Next() {
var domain Domain
err = rows.Scan(&domain.Id, &domain.ApiKey, &domain.Domain, &domain.A)
if err != nil {
return nil, err
}
domains = append(domains, domain)
}
err = rows.Err()
if err != nil {
return nil, err
}
return domains, nil
}
func FetchAllDomains() ([]Domain, error) {
rows, err := DBConn.Query(`SELECT id, ddns_domain, a_record, owner
FROM domains`)
if err != nil {
return nil, err
}
defer rows.Close()
var domains []Domain
for rows.Next() {
var domain Domain
err = rows.Scan(&domain.Id, &domain.Domain, &domain.A, &domain.Owner.ID)
if err != nil {
return nil, err
}
ownerEmail, err := FetchUserEmail(domain.Owner.ID)
if err != nil {
return nil, err
}
domain.Owner.Email = ownerEmail
domains = append(domains, domain)
}
err = rows.Err()
if err != nil {
return nil, err
}
return domains, nil
}
func CreateDomain(domain string, aRecord string, owner string) error {
ulid := ulid.Make().String()
apikey := util.GenApiKey()
_, err := DBConn.Exec(`INSERT INTO domains(id, apikey, ddns_domain, a_record, owner)
VALUES ($1, $2, $3, $4, $5)`, ulid, apikey, domain, aRecord, owner)
if err != nil {
return err
}
return nil
}
func DeleteDomain(id string, user_id string) error {
_, err := DBConn.Exec(`DELETE FROM domains WHERE id = $1 AND owner = $2`, id, user_id)
if err != nil {
return err
}
return nil
}
func DeleteDomainsForUser(userId string) error {
_, err := DBConn.Exec(`DELETE FROM domains WHERE owner = $1`, userId)
if err != nil {
return err
}
return nil
}
func FetchDomainARecord(ddns_domain string) (string, error) {
var aRecord string
err := DBConn.QueryRow(`SELECT a_record FROM domains WHERE ddns_domain = $1`,
ddns_domain).Scan(&aRecord)
if err != nil {
return "", err
}
return aRecord, nil
}
func UpdateDomainARecord(ddns_domain string, providedApiKey string, aRecord string) error {
var domainApiKey string
err := DBConn.QueryRow(`SELECT apikey FROM domains WHERE ddns_domain = $1`,
ddns_domain).Scan(&domainApiKey)
if err != nil {
return err
}
if domainApiKey != providedApiKey {
return errors.New("API key doesn't match")
}
_, err = DBConn.Exec(`UPDATE domains SET a_record = $1 WHERE ddns_domain = $2`,
aRecord, ddns_domain)
if err != nil {
return err
}
return nil
}
func UpdateDomainARecordManual(id string, userId string, aRecord string) error {
_, err := DBConn.Exec(`UPDATE domains SET a_record = $1 WHERE id = $2 AND owner = $3`,
aRecord, id, userId)
if err != nil {
return err
}
return nil
}
func RefreshDomainApiKey(id string, user_id string) error {
apiKey := util.GenApiKey()
_, err := DBConn.Exec(`UPDATE domains SET apikey = $1 WHERE id = $2 AND owner = $3`, apiKey, id, user_id)
if err != nil {
return err
}
return nil
}