mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
249 lines
7.0 KiB
Go
249 lines
7.0 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
var db *gorm.DB
|
|
|
|
// InitDB initializes the SQLite database connection
|
|
func InitDB() error {
|
|
// Create ~/.sonr directory if it doesn't exist
|
|
homeDir, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get user home directory: %w", err)
|
|
}
|
|
|
|
sonrDir := filepath.Join(homeDir, ".sonr")
|
|
if mkdirErr := os.MkdirAll(sonrDir, 0o750); mkdirErr != nil {
|
|
return fmt.Errorf("failed to create .sonr directory: %w", mkdirErr)
|
|
}
|
|
|
|
// Database file path
|
|
dbPath := filepath.Join(sonrDir, "vault.db")
|
|
|
|
// Open SQLite database with GORM
|
|
db, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{
|
|
// Disable GORM logging for cleaner CLI output
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to connect to database: %w", err)
|
|
}
|
|
|
|
// Auto-migrate all models
|
|
err = db.AutoMigrate(
|
|
&StoredWebAuthnCredential{},
|
|
&UnsignedTransaction{},
|
|
&AccountInfo{},
|
|
&VaultInfo{},
|
|
&SessionInfo{},
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to migrate database: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetDB returns the database instance
|
|
func GetDB() *gorm.DB {
|
|
return db
|
|
}
|
|
|
|
// CloseDB closes the database connection
|
|
func CloseDB() error {
|
|
if db == nil {
|
|
return nil
|
|
}
|
|
|
|
sqlDB, err := db.DB()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return sqlDB.Close()
|
|
}
|
|
|
|
// WebAuthnCredentialService provides database operations for WebAuthn credentials
|
|
type WebAuthnCredentialService struct{}
|
|
|
|
// NewWebAuthnCredentialService creates a new WebAuthn credential service
|
|
func NewWebAuthnCredentialService() *WebAuthnCredentialService {
|
|
return &WebAuthnCredentialService{}
|
|
}
|
|
|
|
// Store saves a WebAuthn credential to the database
|
|
func (s *WebAuthnCredentialService) Store(credential *StoredWebAuthnCredential) error {
|
|
return db.Create(credential).Error
|
|
}
|
|
|
|
// GetByCredentialID retrieves a credential by its ID
|
|
func (s *WebAuthnCredentialService) GetByCredentialID(
|
|
credentialID string,
|
|
) (*StoredWebAuthnCredential, error) {
|
|
var credential StoredWebAuthnCredential
|
|
err := db.Where("credential_id = ?", credentialID).First(&credential).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &credential, nil
|
|
}
|
|
|
|
// GetByUsername retrieves all credentials for a username
|
|
func (s *WebAuthnCredentialService) GetByUsername(
|
|
username string,
|
|
) ([]StoredWebAuthnCredential, error) {
|
|
var credentials []StoredWebAuthnCredential
|
|
err := db.Where("username = ?", username).Find(&credentials).Error
|
|
return credentials, err
|
|
}
|
|
|
|
// UsernameExists checks if a username already has registered WebAuthn credentials
|
|
func (s *WebAuthnCredentialService) UsernameExists(username string) (bool, error) {
|
|
var count int64
|
|
err := db.Model(&StoredWebAuthnCredential{}).Where("username = ?", username).Count(&count).Error
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return count > 0, nil
|
|
}
|
|
|
|
// AccountInfoService provides database operations for account information
|
|
type AccountInfoService struct{}
|
|
|
|
// NewAccountInfoService creates a new account info service
|
|
func NewAccountInfoService() *AccountInfoService {
|
|
return &AccountInfoService{}
|
|
}
|
|
|
|
// Store saves account information to the database
|
|
func (s *AccountInfoService) Store(account *AccountInfo) error {
|
|
return db.Create(account).Error
|
|
}
|
|
|
|
// GetByUsername retrieves account info by username
|
|
func (s *AccountInfoService) GetByUsername(username string) (*AccountInfo, error) {
|
|
var account AccountInfo
|
|
err := db.Where("username = ?", username).First(&account).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &account, nil
|
|
}
|
|
|
|
// UpdateSequence updates the account sequence number
|
|
func (s *AccountInfoService) UpdateSequence(username string, sequence uint64) error {
|
|
return db.Model(&AccountInfo{}).
|
|
Where("username = ?", username).
|
|
Update("sequence", sequence).
|
|
Error
|
|
}
|
|
|
|
// VaultInfoService provides database operations for vault information
|
|
type VaultInfoService struct{}
|
|
|
|
// NewVaultInfoService creates a new vault info service
|
|
func NewVaultInfoService() *VaultInfoService {
|
|
return &VaultInfoService{}
|
|
}
|
|
|
|
// Store saves vault information to the database
|
|
func (s *VaultInfoService) Store(vault *VaultInfo) error {
|
|
return db.Create(vault).Error
|
|
}
|
|
|
|
// GetByVaultID retrieves vault info by vault ID
|
|
func (s *VaultInfoService) GetByVaultID(vaultID string) (*VaultInfo, error) {
|
|
var vault VaultInfo
|
|
err := db.Where("vault_id = ?", vaultID).First(&vault).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &vault, nil
|
|
}
|
|
|
|
// GetByUsername retrieves all vaults for a username
|
|
func (s *VaultInfoService) GetByUsername(username string) ([]VaultInfo, error) {
|
|
var vaults []VaultInfo
|
|
err := db.Where("username = ?", username).Find(&vaults).Error
|
|
return vaults, err
|
|
}
|
|
|
|
// UnsignedTransactionService provides database operations for unsigned transactions
|
|
type UnsignedTransactionService struct{}
|
|
|
|
// NewUnsignedTransactionService creates a new unsigned transaction service
|
|
func NewUnsignedTransactionService() *UnsignedTransactionService {
|
|
return &UnsignedTransactionService{}
|
|
}
|
|
|
|
// Store saves an unsigned transaction to the database
|
|
func (s *UnsignedTransactionService) Store(tx *UnsignedTransaction) error {
|
|
return db.Create(tx).Error
|
|
}
|
|
|
|
// GetByTxID retrieves a transaction by its ID
|
|
func (s *UnsignedTransactionService) GetByTxID(txID string) (*UnsignedTransaction, error) {
|
|
var tx UnsignedTransaction
|
|
err := db.Where("tx_id = ?", txID).First(&tx).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &tx, nil
|
|
}
|
|
|
|
// GetPendingByUsername retrieves all pending transactions for a username
|
|
func (s *UnsignedTransactionService) GetPendingByUsername(
|
|
username string,
|
|
) ([]UnsignedTransaction, error) {
|
|
var transactions []UnsignedTransaction
|
|
err := db.Where("username = ? AND status = ?", username, "pending").Find(&transactions).Error
|
|
return transactions, err
|
|
}
|
|
|
|
// UpdateStatus updates the transaction status
|
|
func (s *UnsignedTransactionService) UpdateStatus(txID, status string) error {
|
|
return db.Model(&UnsignedTransaction{}).Where("tx_id = ?", txID).Update("status", status).Error
|
|
}
|
|
|
|
// SessionInfoService provides database operations for session information
|
|
type SessionInfoService struct{}
|
|
|
|
// NewSessionInfoService creates a new session info service
|
|
func NewSessionInfoService() *SessionInfoService {
|
|
return &SessionInfoService{}
|
|
}
|
|
|
|
// Store saves session information to the database
|
|
func (s *SessionInfoService) Store(session *SessionInfo) error {
|
|
return db.Create(session).Error
|
|
}
|
|
|
|
// GetBySessionID retrieves a session by its ID
|
|
func (s *SessionInfoService) GetBySessionID(sessionID string) (*SessionInfo, error) {
|
|
var session SessionInfo
|
|
err := db.Where("session_id = ?", sessionID).First(&session).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &session, nil
|
|
}
|
|
|
|
// UpdateStatus updates the session status
|
|
func (s *SessionInfoService) UpdateStatus(sessionID, status string) error {
|
|
return db.Model(&SessionInfo{}).
|
|
Where("session_id = ?", sessionID).
|
|
Update("status", status).
|
|
Error
|
|
}
|
|
|
|
// CleanupExpiredSessions removes expired sessions
|
|
func (s *SessionInfoService) CleanupExpiredSessions() error {
|
|
return db.Where("expires_at < ?", fmt.Sprintf("%d", os.Getpid())).Delete(&SessionInfo{}).Error
|
|
}
|