remove preact and create setup wizard
This commit is contained in:
@@ -100,6 +100,93 @@ func (r *Repository) CountAdmins(ctx context.Context) (int, error) {
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetInstanceSettings(ctx context.Context) (InstanceSettings, error) {
|
||||
var setupCompleted string
|
||||
var signupsEnabled int
|
||||
if err := r.db.QueryRowContext(ctx, `
|
||||
SELECT COALESCE(setup_completed_at, ''), signups_enabled
|
||||
FROM instance_settings
|
||||
WHERE id = 1
|
||||
`).Scan(&setupCompleted, &signupsEnabled); err != nil {
|
||||
return InstanceSettings{}, fmt.Errorf("get instance settings: %w", err)
|
||||
}
|
||||
return InstanceSettings{
|
||||
SetupComplete: setupCompleted != "",
|
||||
SignupsEnabled: signupsEnabled == 1,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Repository) CompleteInitialSetup(ctx context.Context, user User, signupsEnabled bool) (User, error) {
|
||||
now := time.Now().UTC()
|
||||
if user.ID == "" {
|
||||
user.ID = "user:" + user.Email
|
||||
}
|
||||
if user.DisplayName == "" {
|
||||
user.DisplayName = user.Email
|
||||
}
|
||||
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return User{}, fmt.Errorf("begin initial setup: %w", err)
|
||||
}
|
||||
defer func() { _ = tx.Rollback() }()
|
||||
|
||||
var setupCompleted string
|
||||
if err := tx.QueryRowContext(ctx, `
|
||||
SELECT COALESCE(setup_completed_at, '')
|
||||
FROM instance_settings
|
||||
WHERE id = 1
|
||||
`).Scan(&setupCompleted); err != nil {
|
||||
return User{}, fmt.Errorf("get initial setup state: %w", err)
|
||||
}
|
||||
if setupCompleted != "" {
|
||||
return User{}, fmt.Errorf("initial setup has already been completed")
|
||||
}
|
||||
|
||||
var userCount int
|
||||
if err := tx.QueryRowContext(ctx, `SELECT COUNT(*) FROM users`).Scan(&userCount); err != nil {
|
||||
return User{}, fmt.Errorf("count users during initial setup: %w", err)
|
||||
}
|
||||
if userCount != 0 {
|
||||
return User{}, fmt.Errorf("initial setup requires an empty user database")
|
||||
}
|
||||
|
||||
if _, err := tx.ExecContext(ctx, `
|
||||
INSERT INTO users (id, email, display_name, password_hash, role, created_at, last_seen_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
`, user.ID, user.Email, user.DisplayName, nullString(user.PasswordHash), string(RoleAdmin), now.Format(time.RFC3339), now.Format(time.RFC3339)); err != nil {
|
||||
return User{}, fmt.Errorf("create initial admin: %w", err)
|
||||
}
|
||||
|
||||
if _, err := tx.ExecContext(ctx, `
|
||||
UPDATE instance_settings
|
||||
SET setup_completed_at = ?, signups_enabled = ?, updated_at = ?
|
||||
WHERE id = 1 AND setup_completed_at IS NULL
|
||||
`, now.Format(time.RFC3339), boolInt(signupsEnabled), now.Format(time.RFC3339)); err != nil {
|
||||
return User{}, fmt.Errorf("complete initial setup: %w", err)
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return User{}, fmt.Errorf("commit initial setup: %w", err)
|
||||
}
|
||||
return r.GetUserByEmail(ctx, user.Email)
|
||||
}
|
||||
|
||||
func (r *Repository) UpdateSignupsEnabled(ctx context.Context, enabled bool) error {
|
||||
result, err := r.db.ExecContext(ctx, `
|
||||
UPDATE instance_settings
|
||||
SET signups_enabled = ?, updated_at = ?
|
||||
WHERE id = 1 AND setup_completed_at IS NOT NULL
|
||||
`, boolInt(enabled), time.Now().UTC().Format(time.RFC3339))
|
||||
if err != nil {
|
||||
return fmt.Errorf("update signup setting: %w", err)
|
||||
}
|
||||
if rows, _ := result.RowsAffected(); rows == 0 {
|
||||
return fmt.Errorf("initial setup is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) ListUsers(ctx context.Context) ([]User, error) {
|
||||
rows, err := r.db.QueryContext(ctx, `
|
||||
SELECT id, email, COALESCE(display_name, ''), COALESCE(password_hash, ''), COALESCE(role, 'viewer'), created_at, COALESCE(last_seen_at, '')
|
||||
@@ -522,6 +609,13 @@ func nullString(value string) any {
|
||||
return value
|
||||
}
|
||||
|
||||
func boolInt(value bool) int {
|
||||
if value {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func timePtrString(value *time.Time) any {
|
||||
if value == nil {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user