Compare commits

...

3 Commits

Author SHA1 Message Date
228d1bffc1 Update dockerfile build image 2025-09-16 12:26:13 +03:30
6d15ce2df9 Improved logging with zap 2025-09-16 12:23:12 +03:30
5680f9471f Added some comments for myself 2025-09-16 12:18:35 +03:30
5 changed files with 22 additions and 17 deletions

View File

@@ -3,7 +3,7 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
# Build the application from source # Build the application from source
FROM golang:1.24.3 AS build-stage FROM golang:1.25.1-alpine3.22 AS build-stage
WORKDIR /app WORKDIR /app

View File

@@ -18,6 +18,9 @@ import (
func main() { func main() {
fx.New( fx.New(
fx.Provide( fx.Provide(
// Logger
NewLogger,
// Configuration // Configuration
config.Load, config.Load,
@@ -37,9 +40,6 @@ func main() {
handlers.NewApiEndpointHandler, handlers.NewApiEndpointHandler,
handlers.NewEmbedCardHandler, handlers.NewEmbedCardHandler,
handlers.NewOauthLoginHandler, handlers.NewOauthLoginHandler,
// Logger
NewLogger,
), ),
fx.Invoke( fx.Invoke(
// Start background tasks // Start background tasks

View File

@@ -5,13 +5,15 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io" "io"
"log/slog"
"net/http" "net/http"
"net/url" "net/url"
"go.uber.org/zap"
) )
type GiteaOAuth2Handler struct { type GiteaOAuth2Handler struct {
cfg *config.Config cfg *config.Config
logger *zap.Logger
} }
func NewGiteaOauth2Token(cfg *config.Config) *GiteaOAuth2Handler { func NewGiteaOauth2Token(cfg *config.Config) *GiteaOAuth2Handler {
@@ -24,7 +26,7 @@ func (g *GiteaOAuth2Handler) GetGiteaLoginURL(redirectHost string) (string, erro
} }
if redirectHost == "" { if redirectHost == "" {
slog.Error("Redirect host not provided") g.logger.Error("Redirect host not provided")
return "", nil return "", nil
} }
@@ -35,7 +37,7 @@ func (g *GiteaOAuth2Handler) GetGiteaLoginURL(redirectHost string) (string, erro
func (g *GiteaOAuth2Handler) GetGiteaUserEmailByCode(code string) (string, error) { func (g *GiteaOAuth2Handler) GetGiteaUserEmailByCode(code string) (string, error) {
if g.cfg.GiteaOauthInstance == "" { if g.cfg.GiteaOauthInstance == "" {
slog.Error("Instance URL not provided") g.logger.Error("Instance URL not provided")
return "", nil return "", nil
} }
// No need to verify since we are accesing the gitea once and only for the email // No need to verify since we are accesing the gitea once and only for the email
@@ -45,7 +47,7 @@ func (g *GiteaOAuth2Handler) GetGiteaUserEmailByCode(code string) (string, error
} }
userInfoUrl := g.cfg.GiteaOauthInstance + "/login/oauth/userinfo" userInfoUrl := g.cfg.GiteaOauthInstance + "/login/oauth/userinfo"
slog.Info(userInfoUrl) g.logger.Info(userInfoUrl)
req, err := http.NewRequest("POST", userInfoUrl, nil) req, err := http.NewRequest("POST", userInfoUrl, nil)
if err != nil { if err != nil {
return "", err return "", err

View File

@@ -1,11 +1,11 @@
package config package config
import ( import (
"log/slog"
"os" "os"
"strings" "strings"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"go.uber.org/zap"
) )
type Config struct { type Config struct {
@@ -32,10 +32,10 @@ type Config struct {
GiteaOauthAllowedEmails []string GiteaOauthAllowedEmails []string
} }
func Load() *Config { func Load(logger *zap.Logger) *Config {
err := godotenv.Load() err := godotenv.Load()
if err != nil { if err != nil {
slog.Warn("Error loading .env file - Using environment variables instead") logger.Warn("Error loading .env file - Using environment variables instead")
} }
// Get mastodon instance // Get mastodon instance
@@ -51,7 +51,7 @@ func Load() *Config {
// Get admin password (Its a single user/admin app so its just fine) // Get admin password (Its a single user/admin app so its just fine)
adminPassword := os.Getenv("CAOM_ADMIN_PASSWORD") adminPassword := os.Getenv("CAOM_ADMIN_PASSWORD")
if adminPassword == "" { if adminPassword == "" {
slog.Warn("No admin password provided, using default password 'catsaregood'") logger.Warn("No admin password provided, using default password 'catsaregood'")
adminPassword = "catsaregood" adminPassword = "catsaregood"
} }
@@ -62,12 +62,12 @@ func Load() *Config {
} }
issuer := os.Getenv("CAOM_JWT_ISSUER") issuer := os.Getenv("CAOM_JWT_ISSUER")
if issuer == "" { if issuer == "" {
slog.Info("No jwt issuer provided, using default issuer 'CatsOfMastodonBotGo'") logger.Info("No jwt issuer provided, using default issuer 'CatsOfMastodonBotGo'")
issuer = "CatsOfMastodonBotGo" issuer = "CatsOfMastodonBotGo"
} }
audience := os.Getenv("CAOM_JWT_AUDIENCE") audience := os.Getenv("CAOM_JWT_AUDIENCE")
if audience == "" { if audience == "" {
slog.Info("No jwt audience provided, using default audience 'CatsOfMastodonBotGo'") logger.Info("No jwt audience provided, using default audience 'CatsOfMastodonBotGo'")
audience = "CatsOfMastodonBotGo" audience = "CatsOfMastodonBotGo"
} }
@@ -89,7 +89,7 @@ func Load() *Config {
} }
if dbEngine == "" || dbHost == "" || dbPort == "" || dbUser == "" || dbPassword == "" || dbName == "" { if dbEngine == "" || dbHost == "" || dbPort == "" || dbUser == "" || dbPassword == "" || dbName == "" {
slog.Info("No database connection provided, using sqlite") logger.Info("No database connection provided, using sqlite")
dbEngine = "sqlite" dbEngine = "sqlite"
dbHost = "" dbHost = ""
dbPort = "" dbPort = ""
@@ -100,7 +100,7 @@ func Load() *Config {
imageKitId := os.Getenv("CAOM_IMAGEKIT_ID") imageKitId := os.Getenv("CAOM_IMAGEKIT_ID")
if imageKitId == "" { if imageKitId == "" {
slog.Info("No imagekit id provided, not using imagekit.io") logger.Info("No imagekit id provided, not using imagekit.io")
} }
// Initialize AppContext // Initialize AppContext
return &Config{ return &Config{
@@ -126,4 +126,4 @@ func Load() *Config {
GiteaOauthClientSecret: giteaOauthClientSecret, GiteaOauthClientSecret: giteaOauthClientSecret,
GiteaOauthAllowedEmails: giteaOauthAllowedEmailsParsed, GiteaOauthAllowedEmails: giteaOauthAllowedEmailsParsed,
} }
} }

View File

@@ -13,6 +13,9 @@ import (
) )
// fx.In allows fx to inject multiple dependencies // fx.In allows fx to inject multiple dependencies
// I think we could just put all thses in SetupRouter() but in this way we are first defining the dependencies we need
// and by using fx.In we say that whenever RouterParams was needed, inject dependensies into it and give it to SetupRouter()
type RouterParams struct { type RouterParams struct {
fx.In fx.In