package store import ( "fmt" "time" "git.misaka.ren/M1saka/zhanlu_proxy/internal/auth" ) // LoadCredentials reads the persisted credentials. The credentials row always // exists after Open; an empty row (nothing saved yet) yields a zero-value // Credentials with a nil error — callers check Validate()/HasAPIKey(). func (s *Store) LoadCredentials() (auth.Credentials, error) { var c auth.Credentials var savedAt int64 err := s.db.QueryRow(`SELECT access_key, secret_key, token, api_key, model_base_url, email, organization, team, base_url, saved_at FROM credentials WHERE id = 1`). Scan(&c.AccessKey, &c.SecretKey, &c.Token, &c.APIKey, &c.ModelBaseURL, &c.Email, &c.Organization, &c.Team, &c.BaseURL, &savedAt) if err != nil { return auth.Credentials{}, fmt.Errorf("load credentials: %w", err) } c.SavedAt = time.Unix(savedAt, 0).Local() return c, nil } // SaveCredentials upserts the credentials into the single row. It only writes // when the credentials validate or already carry an API key, so partial / // env-only creds are not persisted. func (s *Store) SaveCredentials(c auth.Credentials) error { if c.Validate() != nil && !c.HasAPIKey() { return fmt.Errorf("save credentials: %w", c.Validate()) } c.SavedAt = time.Now() _, err := s.db.Exec(`INSERT INTO credentials (id, access_key, secret_key, token, api_key, model_base_url, email, organization, team, base_url, saved_at) VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET access_key=excluded.access_key, secret_key=excluded.secret_key, token=excluded.token, api_key=excluded.api_key, model_base_url=excluded.model_base_url, email=excluded.email, organization=excluded.organization, team=excluded.team, base_url=excluded.base_url, saved_at=excluded.saved_at`, c.AccessKey, c.SecretKey, c.Token, c.APIKey, c.ModelBaseURL, c.Email, c.Organization, c.Team, c.BaseURL, c.SavedAt.Unix()) if err != nil { return fmt.Errorf("save credentials: %w", err) } return nil }