MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m31s
Pure moves, no behaviour change: the storage layer now has users, apikeys, thoughts, tasklists, documents, folders, tags, lists, teams and system files next to sqlite.go (store, schema, migrations); the API has handlers_*.go per area plus realtime.go and alarms.go next to server.go (server, router, middleware). Declarations were moved verbatim with an AST-based tool; imports pruned with goimports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
76 lines
2.0 KiB
Go
76 lines
2.0 KiB
Go
package storage
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/sandrodach/mindsift/internal/auth"
|
|
"github.com/sandrodach/mindsift/internal/domain"
|
|
)
|
|
|
|
// --- API KEYS & WEBHOOKS ---
|
|
|
|
func (s *Store) CreateAPIKey(userID, name string) (*domain.APIKey, error) {
|
|
if strings.TrimSpace(name) == "" {
|
|
name = "Smarthome / Webhook Key"
|
|
}
|
|
rawKey, prefix, hash := auth.GenerateAPIKey()
|
|
k := &domain.APIKey{
|
|
ID: domain.NewID("key"),
|
|
UserID: userID,
|
|
Name: strings.TrimSpace(name),
|
|
KeyPrefix: prefix,
|
|
KeyHash: hash,
|
|
RawKey: rawKey,
|
|
Scopes: "ingest,read",
|
|
CreatedAt: domain.NowISO(),
|
|
}
|
|
|
|
_, err := s.db.Exec(
|
|
`INSERT INTO api_keys (id, user_id, name, key_prefix, key_hash, scopes, created_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
k.ID, k.UserID, k.Name, k.KeyPrefix, k.KeyHash, k.Scopes, k.CreatedAt,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return k, nil
|
|
}
|
|
|
|
func (s *Store) GetAPIKeys(userID string) ([]domain.APIKey, error) {
|
|
rows, err := s.db.Query(
|
|
`SELECT id, user_id, name, key_prefix, scopes, last_used_at, created_at
|
|
FROM api_keys WHERE user_id = ? ORDER BY created_at DESC`,
|
|
userID,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
keys := make([]domain.APIKey, 0)
|
|
for rows.Next() {
|
|
var k domain.APIKey
|
|
if err := rows.Scan(&k.ID, &k.UserID, &k.Name, &k.KeyPrefix, &k.Scopes, &k.LastUsedAt, &k.CreatedAt); err == nil {
|
|
keys = append(keys, k)
|
|
}
|
|
}
|
|
return keys, nil
|
|
}
|
|
|
|
func (s *Store) DeleteAPIKey(userID, keyID string) error {
|
|
_, err := s.db.Exec(`DELETE FROM api_keys WHERE id = ? AND user_id = ?`, keyID, userID)
|
|
return err
|
|
}
|
|
|
|
func (s *Store) ValidateAPIKeyAndGetUser(rawKey string) (*domain.User, error) {
|
|
hash := auth.HashAPIKey(strings.TrimSpace(rawKey))
|
|
var keyID, userID string
|
|
err := s.db.QueryRow(`SELECT id, user_id FROM api_keys WHERE key_hash = ?`, hash).Scan(&keyID, &userID)
|
|
if err != nil {
|
|
return nil, errors.New("invalid API key")
|
|
}
|
|
_, _ = s.db.Exec(`UPDATE api_keys SET last_used_at = ? WHERE id = ?`, domain.NowISO(), keyID)
|
|
return s.GetUserByID(userID)
|
|
}
|