Compare commits

..

6 commits

Author SHA1 Message Date
012ace2fc9 Use hash in session db key to reduce key size (required for oracle-nosql)
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-12 10:19:33 +07:00
638bc1b4d0 Bump dnscontrol to 4.30.0 2026-01-12 10:19:33 +07:00
9657345cd6 Add PostgreSQL storage backend support 2026-01-12 10:19:33 +07:00
f7cc234407 Don't display NO FIELD in production mode 2026-01-12 10:19:33 +07:00
0794192679 Update and migrate GSuite to store records instead of generating them 2026-01-12 10:19:33 +07:00
2d39de5eb9 Add service initialization endpoint with DNS type detection
Implement backend-driven service initialization to replace hazardous
frontend initialization logic. Services can now provide custom
initialization via ServiceInitializer interface or get sensible
defaults automatically.
2026-01-12 10:19:33 +07:00
5 changed files with 73 additions and 7 deletions

View file

@ -24,5 +24,5 @@ package main
//go:generate go run tools/gen_icon.go providers providers
//go:generate go run tools/gen_icon.go services svcs
//go:generate go run tools/gen_rr_typescript.go web/src/lib/dns_rr.ts
//go:generate go run tools/gen_dns_type_mapping.go internal/usecase/service_specs_dns_types.go
//go:generate go run tools/gen_dns_type_mapping.go -o internal/usecase/service_specs_dns_types.go
//go:generate swag init --generalInfo internal/api/route/route.go

View file

@ -22,12 +22,21 @@
package database
import (
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"git.happydns.org/happyDomain/model"
)
// sessionKey generates a hashed database key for a session ID
func sessionKey(id string) string {
hash := sha256.Sum256([]byte(id))
encoded := base64.RawURLEncoding.EncodeToString(hash[:])
return fmt.Sprintf("user.session-%s", encoded)
}
func (s *KVStorage) ListAllSessions() (happydns.Iterator[happydns.Session], error) {
iter := s.db.Search("user.session-")
return NewKVIterator[happydns.Session](s.db, iter), nil
@ -43,7 +52,7 @@ func (s *KVStorage) getSession(id string) (*happydns.Session, error) {
}
func (s *KVStorage) GetSession(id string) (session *happydns.Session, err error) {
return s.getSession(fmt.Sprintf("user.session-%s", id))
return s.getSession(sessionKey(id))
}
func (s *KVStorage) ListAuthUserSessions(user *happydns.UserAuth) (sessions []*happydns.Session, err error) {
@ -85,11 +94,11 @@ func (s *KVStorage) ListUserSessions(userid happydns.Identifier) (sessions []*ha
}
func (s *KVStorage) UpdateSession(session *happydns.Session) error {
return s.db.Put(fmt.Sprintf("user.session-%s", session.Id), session)
return s.db.Put(sessionKey(session.Id), session)
}
func (s *KVStorage) DeleteSession(id string) error {
return s.db.Delete(fmt.Sprintf("user.session-%s", id))
return s.db.Delete(sessionKey(id))
}
func (s *KVStorage) ClearSessions() error {

View file

@ -0,0 +1,48 @@
// This file is part of the happyDomain (R) project.
// Copyright (c) 2020-2026 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
//
// This program is offered under a commercial and under the AGPL license.
// For commercial licensing, contact us at <contact@happydomain.org>.
//
// For AGPL licensing:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package database
import (
"log"
)
func migrateFrom9(s *KVStorage) (err error) {
sessions, err := s.ListAllSessions()
if err != nil {
return err
}
for sessions.Next() {
session := sessions.Item()
err := s.UpdateSession(session)
if err != nil {
return err
}
log.Printf("Migrated session %s[...]", session.Id[:10])
err = sessions.DropItem()
if err != nil {
log.Printf("Unable to delete original session %s[...]: %s", session.Id[:10], err.Error())
}
}
return nil
}

View file

@ -38,6 +38,7 @@ var migrations []KVMigrationFunc = []KVMigrationFunc{
migrateFrom6,
migrateFrom7,
migrateFrom8,
migrateFrom9,
}
type Version struct {

View file

@ -25,6 +25,7 @@
package main
import (
"flag"
"fmt"
"os"
"sort"
@ -53,9 +54,16 @@ func getSortedTypes() []uint16 {
}
func main() {
output := os.Args[1]
output := flag.String("o", "", "output file path")
flag.Parse()
fd, err := os.Create(output)
if *output == "" {
fmt.Fprintf(os.Stderr, "Error: output file path is required\n")
fmt.Fprintf(os.Stderr, "Usage: %s -o <output-file>\n", os.Args[0])
os.Exit(1)
}
fd, err := os.Create(*output)
if err != nil {
panic(err)
}
@ -121,5 +129,5 @@ func (ssu *serviceSpecsUsecase) getRRType(t reflect.Type) uint16 {
panic(err)
}
fmt.Printf("Generated %s with %d DNS types\n", output, len(dnsTypes))
fmt.Printf("Generated %s with %d DNS types\n", *output, len(dnsTypes))
}