package db
import (
"errors"
"regexp"
"time"
)
var ErrNameTaken = errors.New("username has already been claimed")
var ErrNameDenied = errors.New("username is on the denylist")
var ErrNameInvalid = errors.New("username has invalid characters in it")
type PublicKey struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Key string `json:"key"`
CreatedAt *time.Time `json:"created_at"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
PublicKey *PublicKey `json:"public_key,omitempty"`
CreatedAt *time.Time `json:"created_at"`
}
type Post struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Filename string `json:"filename"`
Slug string `json:"slug"`
Title string `json:"title"`
Text string `json:"text"`
Description string `json:"description"`
CreatedAt *time.Time `json:"created_at"`
PublishAt *time.Time `json:"publish_at"`
Username string `json:"username"`
UpdatedAt *time.Time `json:"updated_at"`
Hidden bool `json:"hidden"`
Views int `json:"views"`
Space string `json:"space"`
Score string `json:"score"`
}
type Paginate[T any] struct {
Data []T
Total int
}
type Analytics struct {
TotalUsers int
UsersLastMonth int
TotalPosts int
PostsLastMonth int
UsersWithPost int
}
type PostAnalytics struct {
ID string
PostID string
Views int
UpdateAt *time.Time
}
type Pager struct {
Num int
Page int
}
type ErrMultiplePublicKeys struct{}
func (m *ErrMultiplePublicKeys) Error() string {
return "there are multiple users with this public key, you must provide the username when using SSH: `ssh <user>@<domain>`\n"
}
var NameValidator = regexp.MustCompile("^[a-zA-Z0-9]{1,50}$")
var DenyList = []string{
"admin",
"abuse",
"cgi",
"ops",
"help",
"spec",
"root",
"new",
"create",
"www",
}
type DB interface {
AddUser() (string, error)
RemoveUsers(userIDs []string) error
LinkUserKey(userID string, key string) error
FindPublicKeyForKey(key string) (*PublicKey, error)
FindKeysForUser(user *User) ([]*PublicKey, error)
RemoveKeys(keyIDs []string) error
FindSiteAnalytics(space string) (*Analytics, error)
FindUsers() ([]*User, error)
FindUserForName(name string) (*User, error)
FindUserForNameAndKey(name string, key string) (*User, error)
FindUserForKey(name string, key string) (*User, error)
FindUser(userID string) (*User, error)
ValidateName(name string) (bool, error)
SetUserName(userID string, name string) error
FindPosts() ([]*Post, error)
FindPost(postID string) (*Post, error)
FindPostsForUser(userID string, space string) ([]*Post, error)
FindPostsBeforeDate(date *time.Time, space string) ([]*Post, error)
FindUpdatedPostsForUser(userID string, space string) ([]*Post, error)
FindPostWithFilename(filename string, userID string, space string) (*Post, error)
FindPostWithSlug(slug string, userID string, space string) (*Post, error)
FindAllPosts(pager *Pager, space string) (*Paginate[*Post], error)
FindAllUpdatedPosts(pager *Pager, space string) (*Paginate[*Post], error)
InsertPost(userID string, filename string, slug string, title string, text string, description string, publishAt *time.Time, hidden bool, space string) (*Post, error)
UpdatePost(postID string, slug string, title string, text string, description string, publishAt *time.Time) (*Post, error)
RemovePosts(postIDs []string) error
ReplaceTagsForPost(tags []string, postID string) error
FindUserPostsByTag(tag, userID, space string) ([]*Post, error)
FindPostsByTag(tag, space string) ([]*Post, error)
FindPopularTags() ([]string, error)
AddViewCount(postID string) (int, error)
Close() error
}