repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

commit
7fe30e4
parent
78dfe01
author
Eric Bower
date
2026-01-22 18:12:11 -0500 EST
feat(auth): `/pubkeys/{user}` public endpoint
1 files changed,  +45, -6
M pkg/apps/auth/api.go
+45, -6
  1@@ -69,7 +69,7 @@ func wellKnownHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
  2 		w.WriteHeader(http.StatusOK)
  3 		err := json.NewEncoder(w).Encode(p)
  4 		if err != nil {
  5-			apiConfig.Cfg.Logger.Error(err.Error())
  6+			apiConfig.Cfg.Logger.Error("cannot json encode", "err", err.Error())
  7 			http.Error(w, err.Error(), http.StatusInternalServerError)
  8 		}
  9 	}
 10@@ -108,7 +108,7 @@ func introspectHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
 11 		w.WriteHeader(http.StatusOK)
 12 		err = json.NewEncoder(w).Encode(p)
 13 		if err != nil {
 14-			apiConfig.Cfg.Logger.Error(err.Error())
 15+			apiConfig.Cfg.Logger.Error("cannot json encode", "err", err.Error())
 16 			http.Error(w, err.Error(), http.StatusInternalServerError)
 17 		}
 18 	}
 19@@ -151,7 +151,7 @@ func authorizeHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
 20 		})
 21 
 22 		if err != nil {
 23-			apiConfig.Cfg.Logger.Error(err.Error())
 24+			apiConfig.Cfg.Logger.Error("cannot execture template", "err", err.Error())
 25 			http.Error(w, err.Error(), http.StatusUnauthorized)
 26 			return
 27 		}
 28@@ -221,7 +221,7 @@ func tokenHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
 29 		w.WriteHeader(http.StatusOK)
 30 		err = json.NewEncoder(w).Encode(p)
 31 		if err != nil {
 32-			apiConfig.Cfg.Logger.Error(err.Error())
 33+			apiConfig.Cfg.Logger.Error("cannot json encode", "err", err.Error())
 34 			http.Error(w, err.Error(), http.StatusInternalServerError)
 35 		}
 36 	}
 37@@ -348,7 +348,7 @@ func userHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
 38 		w.WriteHeader(http.StatusOK)
 39 		err = json.NewEncoder(w).Encode(keys)
 40 		if err != nil {
 41-			apiConfig.Cfg.Logger.Error(err.Error())
 42+			apiConfig.Cfg.Logger.Error("cannot json encode", "err", err.Error())
 43 			http.Error(w, err.Error(), http.StatusInternalServerError)
 44 		}
 45 	}
 46@@ -382,7 +382,45 @@ func rssHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
 47 		w.Header().Add("Content-Type", "application/atom+xml")
 48 		_, err = w.Write([]byte(rss))
 49 		if err != nil {
 50-			apiConfig.Cfg.Logger.Error(err.Error())
 51+			apiConfig.Cfg.Logger.Error("cannot write to http handler", "err", err.Error())
 52+		}
 53+	}
 54+}
 55+
 56+func pubkeysHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
 57+	return func(w http.ResponseWriter, r *http.Request) {
 58+		userName := r.PathValue("user")
 59+		user, err := apiConfig.Dbpool.FindUserByName(userName)
 60+		if err != nil {
 61+			apiConfig.Cfg.Logger.Error(
 62+				"could not find user by name",
 63+				"err", err.Error(),
 64+				"user", userName,
 65+			)
 66+			http.Error(w, "user not found", http.StatusNotFound)
 67+			return
 68+		}
 69+
 70+		pubkeys, err := apiConfig.Dbpool.FindKeysByUser(user)
 71+		if err != nil {
 72+			apiConfig.Cfg.Logger.Error(
 73+				"could not find pubkeys for user",
 74+				"err", err.Error(),
 75+				"user", userName,
 76+			)
 77+			http.Error(w, "user pubkeys not found", http.StatusNotFound)
 78+			return
 79+		}
 80+
 81+		keys := []string{}
 82+		for _, pubkeys := range pubkeys {
 83+			keys = append(keys, pubkeys.Key)
 84+		}
 85+
 86+		w.Header().Add("Content-Type", "text/plain")
 87+		_, err = w.Write([]byte(strings.Join(keys, "\n")))
 88+		if err != nil {
 89+			apiConfig.Cfg.Logger.Error("cannot write to http handler", "err", err.Error())
 90 		}
 91 	}
 92 }
 93@@ -815,6 +853,7 @@ func authMux(apiConfig *shared.ApiConfig) *http.ServeMux {
 94 	mux.Handle("POST /key", keyHandler(apiConfig))
 95 	mux.Handle("POST /user", userHandler(apiConfig))
 96 	mux.Handle("GET /rss/{token}", rssHandler(apiConfig))
 97+	mux.Handle("GET /pubkeys/{user}", pubkeysHandler(apiConfig))
 98 	mux.Handle("POST /redirect", redirectHandler(apiConfig))
 99 	mux.Handle("POST /webhook", paymentWebhookHandler(apiConfig))
100 	mux.HandleFunc("GET /main.css", fileServer.ServeHTTP)