Files
HostKeeper/internal/models/models.go
T
swanadiva 408681c8e4 feat: Phase 2 UX Polish — theme system, config profiles, error banner, tests
- Add Theme struct with 3 predefined themes (dark/light/druntime)
- Add Profile struct for named configuration profiles
- Add ErrorBanner with severity levels and auto-dismiss
- Add unit tests for theme, error banner, and models
- Update CHANGELOG.md and PROJECT_STATE.md
2026-06-29 11:50:46 +07:00

140 lines
4.2 KiB
Go

package models
import (
"time"
)
// Host represents an SSH host connection configuration
type Host struct {
ID string `json:"id"`
Name string `json:"name"`
Hostname string `json:"hostname"`
Port int `json:"port"`
Username string `json:"username"`
Auth AuthConfig `json:"auth"`
Group string `json:"group,omitempty"`
Tags []string `json:"tags,omitempty"`
Notes string `json:"notes,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
}
// AuthConfig represents authentication configuration
type AuthConfig struct {
Type string `json:"type"` // "password", "key", "both"
Password string `json:"password,omitempty"`
KeyID string `json:"key_id,omitempty"` // Reference to KeyPair ID
}
// KeyPair represents an SSH key pair
type KeyPair struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"` // "rsa", "ed25519", "ecdsa"
PrivateKey string `json:"private_key"`
PublicKey string `json:"public_key,omitempty"`
Passphrase string `json:"passphrase,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Snippet represents a command snippet
type Snippet struct {
ID string `json:"id"`
Name string `json:"name"`
Command string `json:"command"`
Description string `json:"description,omitempty"`
Tags []string `json:"tags,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Profile represents a named configuration profile
type Profile struct {
Name string `json:"name"`
Theme string `json:"theme"`
DefaultGroup string `json:"default_group,omitempty"`
DefaultAuth string `json:"default_auth,omitempty"` // "password", "key", "both"
Editor string `json:"editor,omitempty"`
Notes string `json:"notes,omitempty"`
}
// AppConfig represents the application configuration
type AppConfig struct {
Version string `json:"version"`
DefaultPort int `json:"default_port"`
ConnectionTimeout int `json:"connection_timeout"` // in seconds
Theme string `json:"theme"`
Editor string `json:"editor"`
AutoSync bool `json:"auto_sync"`
SyncProvider string `json:"sync_provider,omitempty"`
// Profiles
Profiles []Profile `json:"profiles,omitempty"`
ActiveProfile string `json:"active_profile,omitempty"`
// Security
EncryptionEnabled bool `json:"encryption_enabled"`
PasswordHash string `json:"password_hash,omitempty"` // SHA-256 hash for verification
KnownHostsFile string `json:"known_hosts_file,omitempty"`
}
// KnownHost represents a verified host key
type KnownHost struct {
Hostname string `json:"hostname"`
Port int `json:"port"`
KeyType string `json:"key_type"` // "ssh-rsa", "ssh-ed25519", etc.
KeyHash string `json:"key_hash"` // Base64-encoded host key
AddedAt time.Time `json:"added_at"`
}
// DefaultConfig returns the default application configuration
func DefaultConfig() *AppConfig {
return &AppConfig{
Version: "1.0.0",
DefaultPort: 22,
ConnectionTimeout: 30,
Theme: "dark",
Editor: "vim",
AutoSync: false,
EncryptionEnabled: false,
Profiles: []Profile{
{
Name: "default",
Theme: "dark",
},
},
ActiveProfile: "default",
}
}
// GetProfile returns a profile by name
func (c *AppConfig) GetProfile(name string) *Profile {
for i := range c.Profiles {
if c.Profiles[i].Name == name {
return &c.Profiles[i]
}
}
return nil
}
// GetActiveProfile returns the active profile
func (c *AppConfig) GetActiveProfile() *Profile {
return c.GetProfile(c.ActiveProfile)
}
// AddProfile adds a new profile
func (c *AppConfig) AddProfile(p Profile) {
c.Profiles = append(c.Profiles, p)
}
// RemoveProfile removes a profile by name
func (c *AppConfig) RemoveProfile(name string) {
for i := range c.Profiles {
if c.Profiles[i].Name == name {
c.Profiles = append(c.Profiles[:i], c.Profiles[i+1:]...)
return
}
}
}