build / build (push) Successful in 2m34s
- New internal/stats (types) and internal/store (SQLite owner: requests + credentials tables, WAL); store implements stats.Recorder. - Stream (SSE tee) and non-stream chat paths parse upstream usage incl. cached_tokens and record per-request; add /api/stats, /api/stats/reset, /admin/stats HTML with cache hit rate. - Drop credentials.json: remove auth file I/O and ZHANLU_CREDENTIALS_FILE; credential precedence is env vars > db row.
46 lines
1.9 KiB
Go
46 lines
1.9 KiB
Go
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
|
|
}
|