mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 15:44:21 +00:00
27 KiB
27 KiB
NovaMD Package Documentation
Generated documentation for all packages in the NovaMD project.
Table of Contents
- cmd/server
- internal/app
- internal/auth
- internal/config
- internal/context
- internal/db
- internal/git
- internal/handlers
- internal/models
- internal/secrets
- internal/storage
cmd/server
Package main provides the entry point for the application. It loads the
configuration, initializes the server, and starts the server.
internal/app
package app // import "novamd/internal/app"
Package app provides application-level functionality for initializing and
running the server
FUNCTIONS
func SetupRoutes(r chi.Router, db db.Database, s storage.Manager, authMiddleware *auth.Middleware, sessionService *auth.SessionService)
SetupRoutes configures the API routes
TYPES
type Server struct {
// Has unexported fields.
}
Server represents the HTTP server and its dependencies
func NewServer(cfg *config.Config) (*Server, error)
NewServer initializes a new server instance with all dependencies
func (s *Server) Close() error
Close handles graceful shutdown of server dependencies
func (s *Server) Start() error
Start configures and starts the HTTP server
internal/auth
package auth // import "novamd/internal/auth"
Package auth provides JWT token generation and validation
TYPES
type Claims struct {
jwt.RegisteredClaims // Embedded standard JWT claims
UserID int `json:"uid"` // User identifier
Role string `json:"role"` // User role (admin, editor, viewer)
Type TokenType `json:"type"` // Token type (access or refresh)
}
Claims represents the custom claims we store in JWT tokens
type JWTConfig struct {
SigningKey string // Secret key used to sign tokens
AccessTokenExpiry time.Duration // How long access tokens are valid
RefreshTokenExpiry time.Duration // How long refresh tokens are valid
}
JWTConfig holds the configuration for the JWT service
type JWTManager interface {
GenerateAccessToken(userID int, role string) (string, error)
GenerateRefreshToken(userID int, role string) (string, error)
ValidateToken(tokenString string) (*Claims, error)
RefreshAccessToken(refreshToken string) (string, error)
}
JWTManager defines the interface for managing JWT tokens
func NewJWTService(config JWTConfig) (JWTManager, error)
NewJWTService creates a new JWT service with the provided configuration
Returns an error if the signing key is missing
type Middleware struct {
// Has unexported fields.
}
Middleware handles JWT authentication for protected routes
func NewMiddleware(jwtManager JWTManager) *Middleware
NewMiddleware creates a new authentication middleware
func (m *Middleware) Authenticate(next http.Handler) http.Handler
Authenticate middleware validates JWT tokens and sets user information in
context
func (m *Middleware) RequireRole(role string) func(http.Handler) http.Handler
RequireRole returns a middleware that ensures the user has the required role
func (m *Middleware) RequireWorkspaceAccess(next http.Handler) http.Handler
RequireWorkspaceAccess returns a middleware that ensures the user has access
to the workspace
type SessionService struct {
// Has unexported fields.
}
SessionService manages user sessions in the database
func NewSessionService(db db.SessionStore, jwtManager JWTManager) *SessionService
NewSessionService creates a new session service with the given database and
JWT manager
func (s *SessionService) CleanExpiredSessions() error
CleanExpiredSessions removes all expired sessions from the database
func (s *SessionService) CreateSession(userID int, role string) (*models.Session, string, error)
CreateSession creates a new user session for a user with the given userID
and role
func (s *SessionService) InvalidateSession(sessionID string) error
InvalidateSession removes a session with the given sessionID from the
database
func (s *SessionService) RefreshSession(refreshToken string) (string, error)
RefreshSession creates a new access token using a refreshToken
type TokenType string
TokenType represents the type of JWT token (access or refresh)
const (
AccessToken TokenType = "access" // AccessToken - Short-lived token for API access
RefreshToken TokenType = "refresh" // RefreshToken - Long-lived token for obtaining new access tokens
)
internal/config
package config // import "novamd/internal/config"
Package config provides the configuration for the application
TYPES
type Config struct {
DBPath string
WorkDir string
StaticPath string
Port string
AppURL string
CORSOrigins []string
AdminEmail string
AdminPassword string
EncryptionKey string
JWTSigningKey string
RateLimitRequests int
RateLimitWindow time.Duration
IsDevelopment bool
}
Config holds the configuration for the application
func DefaultConfig() *Config
DefaultConfig returns a new Config instance with default values
func Load() (*Config, error)
Load creates a new Config instance with values from environment variables
func (c *Config) Validate() error
Validate checks if the configuration is valid
internal/context
package context // import "novamd/internal/context"
Package context provides functions for managing request context
CONSTANTS
const (
// HandlerContextKey is the key used to store handler context in the request context
HandlerContextKey contextKey = "handlerContext"
)
FUNCTIONS
func WithHandlerContext(r *http.Request, hctx *HandlerContext) *http.Request
WithHandlerContext adds handler context to the request
func WithUserContextMiddleware(next http.Handler) http.Handler
WithUserContextMiddleware extracts user information from JWT claims and adds
it to the request context
func WithWorkspaceContextMiddleware(db db.WorkspaceReader) func(http.Handler) http.Handler
WithWorkspaceContextMiddleware adds workspace information to the request
context
TYPES
type HandlerContext struct {
UserID int
UserRole string
Workspace *models.Workspace // Optional, only set for workspace routes
}
HandlerContext holds the request-specific data available to all handlers
func GetRequestContext(w http.ResponseWriter, r *http.Request) (*HandlerContext, bool)
GetRequestContext retrieves the handler context from the request
type UserClaims struct {
UserID int
Role string
}
UserClaims represents user information from authentication
func GetUserFromContext(ctx context.Context) (*UserClaims, error)
GetUserFromContext retrieves user claims from the context
internal/db
package db // import "novamd/internal/db"
Package db provides the database access layer for the application. It contains
methods for interacting with the database, such as creating, updating, and
deleting records.
CONSTANTS
const (
// JWTSecretKey is the key for the JWT secret in the system settings
JWTSecretKey = "jwt_secret"
)
TYPES
type Database interface {
UserStore
WorkspaceStore
SessionStore
SystemStore
Begin() (*sql.Tx, error)
Close() error
Migrate() error
}
Database defines the methods for interacting with the database
func Init(dbPath string, secretsService secrets.Service) (Database, error)
Init initializes the database connection
type Migration struct {
Version int
SQL string
}
Migration represents a database migration
type SessionStore interface {
CreateSession(session *models.Session) error
GetSessionByRefreshToken(refreshToken string) (*models.Session, error)
DeleteSession(sessionID string) error
CleanExpiredSessions() error
}
SessionStore defines the methods for interacting with jwt sessions in the
database
type SystemStore interface {
GetSystemStats() (*UserStats, error)
EnsureJWTSecret() (string, error)
GetSystemSetting(key string) (string, error)
SetSystemSetting(key, value string) error
}
SystemStore defines the methods for interacting with system settings and
stats in the database
type UserStats struct {
TotalUsers int `json:"totalUsers"`
TotalWorkspaces int `json:"totalWorkspaces"`
ActiveUsers int `json:"activeUsers"` // Users with activity in last 30 days
}
UserStats represents system-wide statistics
type UserStore interface {
CreateUser(user *models.User) (*models.User, error)
GetUserByEmail(email string) (*models.User, error)
GetUserByID(userID int) (*models.User, error)
GetAllUsers() ([]*models.User, error)
UpdateUser(user *models.User) error
DeleteUser(userID int) error
UpdateLastWorkspace(userID int, workspaceName string) error
GetLastWorkspaceName(userID int) (string, error)
CountAdminUsers() (int, error)
}
UserStore defines the methods for interacting with user data in the database
type WorkspaceReader interface {
GetWorkspaceByID(workspaceID int) (*models.Workspace, error)
GetWorkspaceByName(userID int, workspaceName string) (*models.Workspace, error)
GetWorkspacesByUserID(userID int) ([]*models.Workspace, error)
GetAllWorkspaces() ([]*models.Workspace, error)
}
WorkspaceReader defines the methods for reading workspace data from the
database
type WorkspaceStore interface {
WorkspaceReader
WorkspaceWriter
}
WorkspaceStore defines the methods for interacting with workspace data in
the database
type WorkspaceWriter interface {
CreateWorkspace(workspace *models.Workspace) error
UpdateWorkspace(workspace *models.Workspace) error
DeleteWorkspace(workspaceID int) error
UpdateWorkspaceSettings(workspace *models.Workspace) error
DeleteWorkspaceTx(tx *sql.Tx, workspaceID int) error
UpdateLastWorkspaceTx(tx *sql.Tx, userID, workspaceID int) error
UpdateLastOpenedFile(workspaceID int, filePath string) error
GetLastOpenedFile(workspaceID int) (string, error)
}
WorkspaceWriter defines the methods for writing workspace data to the
database
internal/git
package git // import "novamd/internal/git"
Package git provides functionalities to interact with Git repositories,
including cloning, pulling, committing, and pushing changes.
TYPES
type Client interface {
Clone() error
Pull() error
Commit(message string) error
Push() error
EnsureRepo() error
}
Client defines the interface for Git operations
func New(url, username, token, workDir, commitName, commitEmail string) Client
New creates a new git Client instance
type Config struct {
URL string
Username string
Token string
WorkDir string
CommitName string
CommitEmail string
}
Config holds the configuration for a Git client
internal/handlers
package handlers // import "novamd/internal/handlers"
Package handlers contains the request handlers for the api routes.
TYPES
type CreateUserRequest struct {
Email string `json:"email"`
DisplayName string `json:"displayName"`
Password string `json:"password"`
Role models.UserRole `json:"role"`
}
CreateUserRequest holds the request fields for creating a new user
type DeleteAccountRequest struct {
Password string `json:"password"`
}
DeleteAccountRequest represents a user account deletion request
type Handler struct {
DB db.Database
Storage storage.Manager
}
Handler provides common functionality for all handlers
func NewHandler(db db.Database, s storage.Manager) *Handler
NewHandler creates a new handler with the given dependencies
func (h *Handler) AdminCreateUser() http.HandlerFunc
AdminCreateUser creates a new user
func (h *Handler) AdminDeleteUser() http.HandlerFunc
AdminDeleteUser deletes a specific user
func (h *Handler) AdminGetSystemStats() http.HandlerFunc
AdminGetSystemStats returns system-wide statistics for admins
func (h *Handler) AdminGetUser() http.HandlerFunc
AdminGetUser gets a specific user by ID
func (h *Handler) AdminListUsers() http.HandlerFunc
AdminListUsers returns a list of all users
func (h *Handler) AdminListWorkspaces() http.HandlerFunc
AdminListWorkspaces returns a list of all workspaces and their stats
func (h *Handler) AdminUpdateUser() http.HandlerFunc
AdminUpdateUser updates a specific user
func (h *Handler) CreateWorkspace() http.HandlerFunc
CreateWorkspace creates a new workspace
func (h *Handler) DeleteAccount() http.HandlerFunc
DeleteAccount handles user account deletion
func (h *Handler) DeleteFile() http.HandlerFunc
DeleteFile deletes a file
func (h *Handler) DeleteWorkspace() http.HandlerFunc
DeleteWorkspace deletes the current workspace
func (h *Handler) GetCurrentUser() http.HandlerFunc
GetCurrentUser returns the currently authenticated user
func (h *Handler) GetFileContent() http.HandlerFunc
GetFileContent returns the content of a file
func (h *Handler) GetLastOpenedFile() http.HandlerFunc
GetLastOpenedFile returns the last opened file in the workspace
func (h *Handler) GetLastWorkspaceName() http.HandlerFunc
GetLastWorkspaceName returns the name of the last opened workspace
func (h *Handler) GetWorkspace() http.HandlerFunc
GetWorkspace returns the current workspace
func (h *Handler) ListFiles() http.HandlerFunc
ListFiles returns a list of all files in the workspace
func (h *Handler) ListWorkspaces() http.HandlerFunc
ListWorkspaces returns a list of all workspaces for the current user
func (h *Handler) Login(authService *auth.SessionService) http.HandlerFunc
Login handles user authentication and returns JWT tokens
func (h *Handler) Logout(authService *auth.SessionService) http.HandlerFunc
Logout invalidates the user's session
func (h *Handler) LookupFileByName() http.HandlerFunc
LookupFileByName returns the paths of files with the given name
func (h *Handler) PullChanges() http.HandlerFunc
PullChanges pulls changes from the remote repository
func (h *Handler) RefreshToken(authService *auth.SessionService) http.HandlerFunc
RefreshToken generates a new access token using a refresh token
func (h *Handler) SaveFile() http.HandlerFunc
SaveFile saves the content of a file
func (h *Handler) StageCommitAndPush() http.HandlerFunc
StageCommitAndPush stages, commits, and pushes changes to the remote
repository
func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc
UpdateLastOpenedFile updates the last opened file in the workspace
func (h *Handler) UpdateLastWorkspaceName() http.HandlerFunc
UpdateLastWorkspaceName updates the name of the last opened workspace
func (h *Handler) UpdateProfile() http.HandlerFunc
UpdateProfile updates the current user's profile
func (h *Handler) UpdateWorkspace() http.HandlerFunc
UpdateWorkspace updates the current workspace
type LoginRequest struct {
Email string `json:"email"`
Password string `json:"password"`
}
LoginRequest represents a user login request
type LoginResponse struct {
AccessToken string `json:"accessToken"`
RefreshToken string `json:"refreshToken"`
User *models.User `json:"user"`
Session *models.Session `json:"session"`
}
LoginResponse represents a user login response
type RefreshRequest struct {
RefreshToken string `json:"refreshToken"`
}
RefreshRequest represents a refresh token request
type RefreshResponse struct {
AccessToken string `json:"accessToken"`
}
RefreshResponse represents a refresh token response
type StaticHandler struct {
// Has unexported fields.
}
StaticHandler serves static files with support for SPA routing and
pre-compressed files
func NewStaticHandler(staticPath string) *StaticHandler
NewStaticHandler creates a new StaticHandler with the given static path
func (h *StaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP serves the static files
type SystemStats struct {
*db.UserStats
*storage.FileCountStats
}
SystemStats holds system-wide statistics
type UpdateProfileRequest struct {
DisplayName string `json:"displayName"`
Email string `json:"email"`
CurrentPassword string `json:"currentPassword"`
NewPassword string `json:"newPassword"`
}
UpdateProfileRequest represents a user profile update request
type UpdateUserRequest struct {
Email string `json:"email,omitempty"`
DisplayName string `json:"displayName,omitempty"`
Password string `json:"password,omitempty"`
Role models.UserRole `json:"role,omitempty"`
}
UpdateUserRequest holds the request fields for updating a user
type WorkspaceStats struct {
UserID int `json:"userID"`
UserEmail string `json:"userEmail"`
WorkspaceID int `json:"workspaceID"`
WorkspaceName string `json:"workspaceName"`
WorkspaceCreatedAt time.Time `json:"workspaceCreatedAt"`
*storage.FileCountStats
}
WorkspaceStats holds workspace statistics
internal/models
package models // import "novamd/internal/models"
Package models contains the data models used throughout the application.
These models are used to represent data in the database, as well as to validate
and serialize data in the application.
TYPES
type Session struct {
ID string // Unique session identifier
UserID int // ID of the user this session belongs to
RefreshToken string // The refresh token associated with this session
ExpiresAt time.Time // When this session expires
CreatedAt time.Time // When this session was created
}
Session represents a user session in the database
type User struct {
ID int `json:"id" validate:"required,min=1"`
Email string `json:"email" validate:"required,email"`
DisplayName string `json:"displayName"`
PasswordHash string `json:"-"`
Role UserRole `json:"role" validate:"required,oneof=admin editor viewer"`
CreatedAt time.Time `json:"createdAt"`
LastWorkspaceID int `json:"lastWorkspaceId"`
}
User represents a user in the system
func (u *User) Validate() error
Validate validates the user struct
type UserRole string
UserRole represents the role of a user in the system
const (
RoleAdmin UserRole = "admin"
RoleEditor UserRole = "editor"
RoleViewer UserRole = "viewer"
)
User roles
type Workspace struct {
ID int `json:"id" validate:"required,min=1"`
UserID int `json:"userId" validate:"required,min=1"`
Name string `json:"name" validate:"required"`
CreatedAt time.Time `json:"createdAt"`
LastOpenedFilePath string `json:"lastOpenedFilePath"`
// Integrated settings
Theme string `json:"theme" validate:"oneof=light dark"`
AutoSave bool `json:"autoSave"`
ShowHiddenFiles bool `json:"showHiddenFiles"`
GitEnabled bool `json:"gitEnabled"`
GitURL string `json:"gitUrl" validate:"required_if=GitEnabled true"`
GitUser string `json:"gitUser" validate:"required_if=GitEnabled true"`
GitToken string `json:"gitToken" validate:"required_if=GitEnabled true"`
GitAutoCommit bool `json:"gitAutoCommit"`
GitCommitMsgTemplate string `json:"gitCommitMsgTemplate"`
GitCommitName string `json:"gitCommitName"`
GitCommitEmail string `json:"gitCommitEmail" validate:"omitempty,required_if=GitEnabled true,email"`
}
Workspace represents a user's workspace in the system
func (w *Workspace) SetDefaultSettings()
SetDefaultSettings sets the default settings for the workspace
func (w *Workspace) Validate() error
Validate validates the workspace struct
func (w *Workspace) ValidateGitSettings() error
ValidateGitSettings validates the git settings if git is enabled
internal/secrets
package secrets // import "novamd/internal/secrets"
Package secrets provides an Encryptor interface for encrypting and decrypting
strings using AES-256-GCM.
FUNCTIONS
func ValidateKey(key string) error
ValidateKey checks if the provided base64-encoded key is suitable for
AES-256
TYPES
type Service interface {
Encrypt(plaintext string) (string, error)
Decrypt(ciphertext string) (string, error)
}
Service is an interface for encrypting and decrypting strings
func NewService(key string) (Service, error)
NewService creates a new Encryptor instance with the provided base64-encoded
key
internal/storage
package storage // import "novamd/internal/storage"
Package storage provides functionalities to interact with the file system,
including listing files, finding files by name, getting file content, saving
files, and deleting files.
FUNCTIONS
func IsPathValidationError(err error) bool
IsPathValidationError checks if the error is a PathValidationError
TYPES
type FileCountStats struct {
TotalFiles int `json:"totalFiles"`
TotalSize int64 `json:"totalSize"`
}
FileCountStats holds statistics about files in a workspace
type FileManager interface {
ListFilesRecursively(userID, workspaceID int) ([]FileNode, error)
FindFileByName(userID, workspaceID int, filename string) ([]string, error)
GetFileContent(userID, workspaceID int, filePath string) ([]byte, error)
SaveFile(userID, workspaceID int, filePath string, content []byte) error
DeleteFile(userID, workspaceID int, filePath string) error
GetFileStats(userID, workspaceID int) (*FileCountStats, error)
GetTotalFileStats() (*FileCountStats, error)
}
FileManager provides functionalities to interact with files in the storage.
type FileNode struct {
ID string `json:"id"`
Name string `json:"name"`
Path string `json:"path"`
Children []FileNode `json:"children,omitempty"`
}
FileNode represents a file or directory in the storage.
type Manager interface {
FileManager
WorkspaceManager
RepositoryManager
}
Manager interface combines all storage interfaces.
type Options struct {
Fs fileSystem
NewGitClient func(url, user, token, path, commitName, commitEmail string) git.Client
}
Options represents the options for the storage service.
type PathValidationError struct {
Path string
Message string
}
PathValidationError represents a path validation error (e.g., path traversal
attempt)
func (e *PathValidationError) Error() string
type RepositoryManager interface {
SetupGitRepo(userID, workspaceID int, gitURL, gitUser, gitToken, commitName, commitEmail string) error
DisableGitRepo(userID, workspaceID int)
StageCommitAndPush(userID, workspaceID int, message string) error
Pull(userID, workspaceID int) error
}
RepositoryManager defines the interface for managing Git repositories.
type Service struct {
RootDir string
GitRepos map[int]map[int]git.Client // map[userID]map[workspaceID]*git.Client
// Has unexported fields.
}
Service represents the file system structure.
func NewService(rootDir string) *Service
NewService creates a new Storage instance with the default options and the
given rootDir root directory.
func NewServiceWithOptions(rootDir string, options Options) *Service
NewServiceWithOptions creates a new Storage instance with the given options
and the given rootDir root directory.
func (s *Service) DeleteFile(userID, workspaceID int, filePath string) error
DeleteFile deletes the file at the given filePath. Path must be a relative
path within the workspace directory given by userID and workspaceID.
func (s *Service) DeleteUserWorkspace(userID, workspaceID int) error
DeleteUserWorkspace deletes the workspace directory for the given userID and
workspaceID.
func (s *Service) DisableGitRepo(userID, workspaceID int)
DisableGitRepo disables the Git repository for the given userID and
workspaceID.
func (s *Service) FindFileByName(userID, workspaceID int, filename string) ([]string, error)
FindFileByName returns a list of file paths that match the given filename.
Files are searched recursively in the workspace directory and its
subdirectories. Workspace is identified by the given userID and workspaceID.
func (s *Service) GetFileContent(userID, workspaceID int, filePath string) ([]byte, error)
GetFileContent returns the content of the file at the given filePath.
Path must be a relative path within the workspace directory given by userID
and workspaceID.
func (s *Service) GetFileStats(userID, workspaceID int) (*FileCountStats, error)
GetFileStats returns the total number of files and related statistics in a
workspace Workspace is identified by the given userID and workspaceID
func (s *Service) GetTotalFileStats() (*FileCountStats, error)
GetTotalFileStats returns the total file statistics for the storage.
func (s *Service) GetWorkspacePath(userID, workspaceID int) string
GetWorkspacePath returns the path to the workspace directory for the given
userID and workspaceID.
func (s *Service) InitializeUserWorkspace(userID, workspaceID int) error
InitializeUserWorkspace creates the workspace directory for the given userID
and workspaceID.
func (s *Service) ListFilesRecursively(userID, workspaceID int) ([]FileNode, error)
ListFilesRecursively returns a list of all files in the workspace directory
and its subdirectories. Workspace is identified by the given userID and
workspaceID.
func (s *Service) Pull(userID, workspaceID int) error
Pull pulls the changes from the remote Git repository. The git repository
belongs to the given userID and is associated with the given workspaceID.
func (s *Service) SaveFile(userID, workspaceID int, filePath string, content []byte) error
SaveFile writes the content to the file at the given filePath. Path must
be a relative path within the workspace directory given by userID and
workspaceID.
func (s *Service) SetupGitRepo(userID, workspaceID int, gitURL, gitUser, gitToken, commitName, commitEmail string) error
SetupGitRepo sets up a Git repository for the given userID and workspaceID.
The repository is cloned from the given gitURL using the given gitUser and
gitToken.
func (s *Service) StageCommitAndPush(userID, workspaceID int, message string) error
StageCommitAndPush stages, commit with the message, and pushes the changes
to the Git repository. The git repository belongs to the given userID and is
associated with the given workspaceID.
func (s *Service) ValidatePath(userID, workspaceID int, path string) (string, error)
ValidatePath validates the if the given path is valid within the workspace
directory. Workspace directory is defined as the directory for the given
userID and workspaceID.
type WorkspaceManager interface {
ValidatePath(userID, workspaceID int, path string) (string, error)
GetWorkspacePath(userID, workspaceID int) string
InitializeUserWorkspace(userID, workspaceID int) error
DeleteUserWorkspace(userID, workspaceID int) error
}
WorkspaceManager provides functionalities to interact with workspaces in the
storage.