package store import ( "context" "database/sql" "time" ) func (s *Store) ListAPIKeys(ctx context.Context) ([]APIKey, error) { rows, err := s.db.QueryContext(ctx, ` SELECT id, name, key_prefix, enabled, last_used_at, created_at FROM api_keys ORDER BY id DESC`) if err != nil { return nil, err } defer rows.Close() return scanAPIKeys(rows) } func (s *Store) CreateAPIKey(ctx context.Context, name, keyPrefix, keyHash string) (*APIKey, error) { res, err := s.db.ExecContext(ctx, ` INSERT INTO api_keys(name, key_prefix, key_hash, enabled) VALUES(?,?,?,1)`, name, keyPrefix, keyHash) if err != nil { return nil, err } id, _ := res.LastInsertId() return s.GetAPIKey(ctx, id) } func (s *Store) GetAPIKey(ctx context.Context, id int64) (*APIKey, error) { row := s.db.QueryRowContext(ctx, ` SELECT id, name, key_prefix, enabled, last_used_at, created_at FROM api_keys WHERE id=?`, id) return scanAPIKey(row) } func (s *Store) DeleteAPIKey(ctx context.Context, id int64) error { _, err := s.db.ExecContext(ctx, `DELETE FROM api_keys WHERE id=?`, id) return err } func (s *Store) VerifyAPIKey(ctx context.Context, keyHash string) (bool, error) { var id int64 err := s.db.QueryRowContext(ctx, ` SELECT id FROM api_keys WHERE key_hash=? AND enabled=1`, keyHash).Scan(&id) if err == sql.ErrNoRows { return false, nil } if err != nil { return false, err } _, _ = s.db.ExecContext(ctx, `UPDATE api_keys SET last_used_at=datetime('now') WHERE id=?`, id) return true, nil } func scanAPIKeys(rows *sql.Rows) ([]APIKey, error) { var out []APIKey for rows.Next() { item, err := scanAPIKeyFromRows(rows) if err != nil { return nil, err } out = append(out, *item) } return out, rows.Err() } func scanAPIKey(row *sql.Row) (*APIKey, error) { var item APIKey var enabled int var lastUsed, created sql.NullString if err := row.Scan(&item.ID, &item.Name, &item.KeyPrefix, &enabled, &lastUsed, &created); err != nil { return nil, err } item.Enabled = enabled == 1 if lastUsed.Valid { if t, err := time.Parse("2006-01-02 15:04:05", lastUsed.String); err == nil { item.LastUsedAt = &t } } if created.Valid { if t, err := time.Parse("2006-01-02 15:04:05", created.String); err == nil { item.CreatedAt = t } } return &item, nil } func scanAPIKeyFromRows(rows *sql.Rows) (*APIKey, error) { var item APIKey var enabled int var lastUsed, created sql.NullString if err := rows.Scan(&item.ID, &item.Name, &item.KeyPrefix, &enabled, &lastUsed, &created); err != nil { return nil, err } item.Enabled = enabled == 1 if lastUsed.Valid { if t, err := time.Parse("2006-01-02 15:04:05", lastUsed.String); err == nil { item.LastUsedAt = &t } } if created.Valid { if t, err := time.Parse("2006-01-02 15:04:05", created.String); err == nil { item.CreatedAt = t } } return &item, nil }