- 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
+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)