aboutsummaryrefslogtreecommitdiff
path: root/backend/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'backend/main.go')
-rw-r--r--backend/main.go73
1 files changed, 37 insertions, 36 deletions
diff --git a/backend/main.go b/backend/main.go
index 27767b0..6585e56 100644
--- a/backend/main.go
+++ b/backend/main.go
@@ -19,14 +19,11 @@ import (
)
var (
- logger *slog.Logger
backendURL string
frontendURL string
- slingshotURL string
sessionsMutex sync.RWMutex
sessions = make(map[string]*auth.OAuthState)
- cache *fetchers.Cache
- pageSize int
+ config *fetchers.Config
)
func init() {
@@ -54,11 +51,11 @@ func init() {
logLevel = slog.LevelError
}
- logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
+ logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: logLevel,
}))
- slingshotURL = os.Getenv("SLINGSHOT_URL")
+ slingshotURL := os.Getenv("SLINGSHOT_URL")
ttlMin := os.Getenv("TTL_MIN")
var expiryMinutes int
@@ -75,12 +72,16 @@ func init() {
redisPassword := os.Getenv("REDIS_PASSWORD")
postCache, err := fetchers.NewCache(redisAddr, redisPassword, expiryMinutes)
if err != nil {
- logger.Error("failed to connect to redis", "error", err)
+ config.Logger.Error("failed to connect to redis", "error", err)
panic(err)
}
- pageSize = 50
- cache = postCache
+ config = &fetchers.Config{
+ SlingshotURL: slingshotURL,
+ PageSize: 50,
+ Logger: logger,
+ Cache: postCache,
+ }
}
func loginHandler(w http.ResponseWriter, r *http.Request) {
@@ -101,7 +102,7 @@ func loginHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("failed to fetch PDS: %v", err), http.StatusInternalServerError)
return
}
- logger.Debug("Resolved DID and PDS", "did", did, "pds", pds)
+ config.Logger.Debug("Resolved DID and PDS", "did", did, "pds", pds)
// fetch oauth metadata from PDS
metadata, err := auth.FetchOAuthMetadata(pds)
@@ -222,7 +223,7 @@ func callbackHandler(w http.ResponseWriter, r *http.Request) {
delete(sessions, state) // remove the partial oauth state from login
sessionsMutex.Unlock()
- logger.Debug("About to set cookie", "token", sessionToken)
+ config.Logger.Debug("About to set cookie", "token", sessionToken)
// set session cookie
http.SetCookie(w, &http.Cookie{
@@ -235,7 +236,7 @@ func callbackHandler(w http.ResponseWriter, r *http.Request) {
MaxAge: 86400 * 30,
})
- logger.Debug("Cookie set, redirecting to frontend", "destination", frontendURL+"/")
+ config.Logger.Debug("Cookie set, redirecting to frontend", "destination", frontendURL+"/")
// redirect to main app
http.Redirect(w, r, frontendURL, http.StatusFound)
@@ -281,9 +282,9 @@ func getSession(cookieValue string) (*auth.OAuthState, error) {
sessionRead := session.Copy()
sessionsMutex.RUnlock()
- logger.Debug("session found", "did", session.DID, "pds", session.PDS, "access token length", len(session.AccessToken), "session keypair", session.KeyPair)
+ config.Logger.Debug("session found", "did", session.DID, "pds", session.PDS, "access token length", len(session.AccessToken), "session keypair", session.KeyPair)
if session.KeyPair != nil {
- logger.Debug("session public key", "key", session.KeyPair.PublicKey)
+ config.Logger.Debug("session public key", "key", session.KeyPair.PublicKey)
}
needsRefresh := time.Now().After(sessionRead.ExpiresAt)
@@ -294,7 +295,7 @@ func getSession(cookieValue string) (*auth.OAuthState, error) {
sessionsMutex.Lock()
delete(sessions, cookieValue)
sessionsMutex.Unlock()
- logger.Error("no authorization servers found for token refresh")
+ config.Logger.Error("no authorization servers found for token refresh")
return nil, fmt.Errorf("no authorization servers found")
}
@@ -310,16 +311,16 @@ func getSession(cookieValue string) (*auth.OAuthState, error) {
}
func postsHandler(w http.ResponseWriter, r *http.Request) {
- logger.Debug("posts handler start")
+ config.Logger.Debug("posts handler start")
cookie, err := r.Cookie("session_token")
if err != nil {
- logger.Error("cookie not received", "error", err)
+ config.Logger.Error("cookie not received", "error", err)
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
- logger.Debug("cookie received", "value", cookie.Value)
+ config.Logger.Debug("cookie received", "value", cookie.Value)
session, err := getSession(cookie.Value)
if err != nil {
@@ -330,42 +331,42 @@ func postsHandler(w http.ResponseWriter, r *http.Request) {
// Fetch app.bsky.feed.post records
var posts []notes.Note
- cached, err := cache.GetPostsByDID(session.DID)
- logger.Debug("cache read", "count", len(cached), "err", err)
+ cached, err := config.Cache.GetPostsByDID(session.DID)
+ config.Logger.Debug("cache read", "count", len(cached), "err", err)
if err != nil {
- logger.Warn("cache read failed, falling back to fetch", "error", err)
+ config.Logger.Warn("cache read failed, falling back to fetch", "error", err)
}
if len(cached) > 0 {
posts = notes.DeduplicateThreads(cached)
} else {
- posts, err = fetchers.FetchAppBskyFeedPostsWithCursor(logger, session.DID, session.PDS, slingshotURL, session, cache, "", pageSize)
+ posts, err = fetchers.FetchAppBskyFeedPostsWithCursor(config, session.DID, session.PDS, session, "")
if err != nil {
- logger.Error("fetching app.bsky.feed.posts failed", "error", err)
+ config.Logger.Error("fetching app.bsky.feed.posts failed", "error", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
- logger.Debug("posts ready", "count", len(posts))
+ config.Logger.Debug("posts ready", "count", len(posts))
// background refetch if cache is running low
- oldestSent, hasOldest := cache.GetOldestSent(session.DID)
+ oldestSent, hasOldest := config.Cache.GetOldestSent(session.DID)
if !hasOldest || len(posts) > 0 {
oldest := posts[len(posts)-1].CreatedAt
- count, _ := cache.CountPostsOlderThan(session.DID, oldest)
- cursor, hasCursor := cache.GetCursor(session.DID)
- logger.Debug("refetch check", "count", count, "pageSize", pageSize, "hasCursor", hasCursor, "oldest", oldest)
- if count < pageSize && hasCursor {
+ count, _ := config.Cache.CountPostsOlderThan(session.DID, oldest)
+ cursor, hasCursor := config.Cache.GetCursor(session.DID)
+ config.Logger.Debug("refetch check", "count", count, "pageSize", config.PageSize, "hasCursor", hasCursor, "oldest", oldest)
+ if count < config.PageSize && hasCursor {
sessionCopy := session.Copy()
- go fetchers.FetchAppBskyFeedPostsWithCursor(logger, sessionCopy.DID, sessionCopy.PDS, slingshotURL, sessionCopy, cache, cursor, pageSize)
+ go fetchers.FetchAppBskyFeedPostsWithCursor(config, sessionCopy.DID, sessionCopy.PDS, sessionCopy, cursor)
}
if !hasOldest || oldest.Before(oldestSent) {
- cache.SetOldestSent(session.DID, oldest)
+ config.Cache.SetOldestSent(session.DID, oldest)
}
}
// return posts
- logger.Debug("successfully fetched posts", "number", len(posts))
+ config.Logger.Debug("successfully fetched posts", "number", len(posts))
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/json")
@@ -389,18 +390,18 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
var currentSession *auth.OAuthState
cookie, err := r.Cookie("session_token")
if err != nil {
- logger.Warn("unauthorized")
+ config.Logger.Warn("unauthorized")
} else {
session, err := getSession(cookie.Value)
if err != nil {
- logger.Warn("invalid session", "error", err)
+ config.Logger.Warn("invalid session", "error", err)
} else {
currentSession = session
}
}
- note, err := fetchers.GetAppBskyFeedPostByURI(logger, uri, slingshotURL, currentSession, cache)
+ note, err := fetchers.GetAppBskyFeedPostByURI(config, uri, currentSession)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -411,7 +412,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
}
func main() {
- defer cache.Close()
+ defer config.Cache.Close()
// serve static files
fs := http.FileServer(http.Dir("../frontend/dist"))