Files
lpra/internal/server/config.go
T
redtea 7cb9da8569 chore: take the version from VERSION.txt only (0.0.3)
VERSION.txt is embedded into the server and the agent, so a plain
go build reports the real version and build.sh no longer injects it.
2026-10-13 14:50:49 +03:00

120 lines
2.9 KiB
Go

package server
import (
"crypto/rand"
"encoding/hex"
lpra "github.com/x-grk/longpolling-remote-access"
)
// Config keys stored in the config table.
const (
cfgHostAddress = "host_address"
cfgEnrollSecret = "enroll_secret"
cfgSetupDone = "setup_done"
cfgInstallCode = "install_code"
cfgUfwEnabled = "ufw_enabled"
)
// DefaultHostAddress is the public URL agents dial by default. It is baked into
// the rendered install.sh and can be changed from the settings page.
const DefaultHostAddress = "https://REDACTED:8445"
// Version is the server build version (see VERSION.txt). It is the newest
// version agents update to.
var Version = lpra.Version
// ensureDefaults seeds the host address and a random enroll secret on first boot.
func (db *DB) ensureDefaults() error {
host, err := db.GetConfig(cfgHostAddress)
if err != nil {
return err
}
if host == "" {
if err := db.SetConfig(cfgHostAddress, DefaultHostAddress); err != nil {
return err
}
}
secret, err := db.GetConfig(cfgEnrollSecret)
if err != nil {
return err
}
if secret == "" {
if err := db.SetConfig(cfgEnrollSecret, randToken()); err != nil {
return err
}
}
code, err := db.GetConfig(cfgInstallCode)
if err != nil {
return err
}
if code == "" {
if err := db.SetConfig(cfgInstallCode, shortCode()); err != nil {
return err
}
}
return nil
}
func (db *DB) HostAddress() string {
v, _ := db.GetConfig(cfgHostAddress)
if v == "" {
return DefaultHostAddress
}
return v
}
func (db *DB) EnrollSecret() string {
v, _ := db.GetConfig(cfgEnrollSecret)
return v
}
// InstallCode returns the short code used for the /i/<code> install one-liner.
func (db *DB) InstallCode() string {
v, _ := db.GetConfig(cfgInstallCode)
return v
}
// UfwEnabled reports whether panel-driven ufw integration is on (default yes).
func (db *DB) UfwEnabled() bool {
v, _ := db.GetConfig(cfgUfwEnabled)
return v != "0"
}
func (db *DB) SetUfwEnabled(on bool) error {
if on {
return db.SetConfig(cfgUfwEnabled, "1")
}
return db.SetConfig(cfgUfwEnabled, "0")
}
func (db *DB) SetupDone() bool {
v, _ := db.GetConfig(cfgSetupDone)
return v == "1"
}
func (db *DB) MarkSetupDone() error { return db.SetConfig(cfgSetupDone, "1") }
// randToken returns 32 bytes of cryptographic randomness as hex (64 chars).
func randToken() string {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
panic("crypto/rand failed: " + err.Error())
}
return hex.EncodeToString(b)
}
// shortCode returns a short, URL-safe, typo-resistant code for install links.
// It avoids ambiguous characters (0/O, 1/l/I) so it is easy to read and type.
func shortCode() string {
const alphabet = "abcdefghjkmnpqrstuvwxyz23456789"
b := make([]byte, 7)
if _, err := rand.Read(b); err != nil {
panic("crypto/rand failed: " + err.Error())
}
for i := range b {
b[i] = alphabet[int(b[i])%len(alphabet)]
}
return string(b)
}