Initial vibeproxy implementation

Self-contained HTTP/HTTPS/TCP/UDP reverse proxy manager written in Go,
with SQLite storage, a Bootstrap 5 admin UI (Go templates, no JS
framework), and a REST API under /api/v1.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QTXFrNP1imCW7jtfL5SZrw
This commit is contained in:
2026-08-17 10:28:59 -05:00
co-authored by Claude Sonnet 5
commit ba1f7c4c03
105 changed files with 9142 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
package database
import (
"database/sql"
"errors"
"time"
"github.com/owen/vibeproxy/internal/models"
)
var ErrNotFound = errors.New("not found")
const timeFmt = "2006-01-02T15:04:05.000Z"
func parseTime(s string) time.Time {
t, _ := time.Parse(timeFmt, s)
return t
}
func GetUserByUsername(db *sql.DB, username string) (*models.User, error) {
row := db.QueryRow(`SELECT id, username, password_hash, must_change_pw, created_at, updated_at FROM users WHERE username = ?`, username)
u := &models.User{}
var mustChange int
var created, updated string
if err := row.Scan(&u.ID, &u.Username, &u.PasswordHash, &mustChange, &created, &updated); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNotFound
}
return nil, err
}
u.MustChangePW = mustChange == 1
u.CreatedAt = parseTime(created)
u.UpdatedAt = parseTime(updated)
return u, nil
}
func CountUsers(db *sql.DB) (int, error) {
var n int
err := db.QueryRow(`SELECT COUNT(*) FROM users`).Scan(&n)
return n, err
}
func CreateUser(db *sql.DB, username, passwordHash string, mustChange bool) error {
_, err := db.Exec(`INSERT INTO users (username, password_hash, must_change_pw) VALUES (?, ?, ?)`, username, passwordHash, boolToInt(mustChange))
return err
}
func UpdateUserPassword(db *sql.DB, username, passwordHash string, mustChange bool) error {
_, err := db.Exec(`UPDATE users SET password_hash = ?, must_change_pw = ?, updated_at = strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE username = ?`, passwordHash, boolToInt(mustChange), username)
return err
}
func boolToInt(b bool) int {
if b {
return 1
}
return 0
}