commit 63f80483bda23dccd216fc52115244e2915f4b46
parent 34edc2496071e3fde781072bbc97f00ec9f5de58
Author: David Eisinger <[email protected]>
Date: Thu, 9 Oct 2025 14:20:46 -0400
Get rid of legacy username
Diffstat:
2 files changed, 33 insertions(+), 69 deletions(-)
diff --git a/internal/api.go b/internal/api.go
@@ -367,13 +367,18 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) {
return
}
}
- if p != "" {
- // If the path is a single segment ending with a trailing dot, treat it
- // as an invalid username route and return 404.
- if !strings.Contains(p, "/") && strings.HasSuffix(p, ".") {
- http.NotFound(w, r)
- return
- }
+ if p != "" {
+ // Only allow static/page handling for GET/HEAD; other methods 404 here
+ if r.Method != http.MethodGet && r.Method != http.MethodHead {
+ http.NotFound(w, r)
+ return
+ }
+ // If the path is a single segment ending with a trailing dot, treat it
+ // as an invalid username route and return 404.
+ if !strings.Contains(p, "/") && strings.HasSuffix(p, ".") {
+ http.NotFound(w, r)
+ return
+ }
// New user page route: /u:{username}
if strings.HasPrefix(p, "u:") {
uname := strings.TrimPrefix(p, "u:")
@@ -471,62 +476,15 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) {
return
}
}
- }
- // Legacy username route: "/{username}" → serve user page when user exists
- if !strings.Contains(p, "/") && !strings.Contains(p, ".") {
- if u, err := db.GetUserByUsername(r.Context(), p); err == nil && u != nil {
- if html, err := RenderPage("user.html", cfg); err == nil {
- // Initial embed for legacy route
- if isOwnerAuthorized(r, u, db) {
- items, err := db.ListBookmarks(r.Context(), u.ID, 50, 0)
- if err == nil {
- resp := make([]bookmarkResponse, 0, len(items))
- for i := range items {
- resp = append(resp, toRespWithArchive(r.Context(), db, &items[i]))
- }
- if b, err := json.Marshal(resp); err == nil {
- inject := []byte("<script>window.MARKY_INITIAL={view:'self',user:" + strconv.Quote(u.Username) + ",results:" + string(b) + "}</script>\n")
- marker := []byte("<script src=\"/app.js\"></script>")
- if i := bytes.Index(html, marker); i >= 0 {
- out := make([]byte, 0, len(html)+len(inject))
- out = append(out, html[:i]...)
- out = append(out, inject...)
- out = append(out, html[i:]...)
- html = out
- }
- }
- }
- } else {
- items, err := db.ListPublicBookmarks(r.Context(), u.ID, 50, 0)
- if err == nil {
- resp := make([]bookmarkResponse, 0, len(items))
- for i := range items {
- resp = append(resp, toRespWithArchive(r.Context(), db, &items[i]))
- }
- if b, err := json.Marshal(resp); err == nil {
- inject := []byte("<script>window.MARKY_INITIAL={view:'public',user:" + strconv.Quote(u.Username) + ",results:" + string(b) + "}</script>\n")
- marker := []byte("<script src=\"/app.js\"></script>")
- if i := bytes.Index(html, marker); i >= 0 {
- out := make([]byte, 0, len(html)+len(inject))
- out = append(out, html[:i]...)
- out = append(out, inject...)
- out = append(out, html[i:]...)
- html = out
- }
- }
- }
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- _, _ = w.Write(html)
- return
- }
- }
+ }
+ // Legacy username route removed: any non-file single segment (not feeds) 404s
+ if !strings.Contains(p, "/") && !strings.Contains(p, ".") && !strings.HasPrefix(p, "u:") {
http.NotFound(w, r)
return
}
- }
- static.ServeHTTP(w, r)
- })
+ }
+ static.ServeHTTP(w, r)
+ })
// Shared handler for JSON and RSS
bookmarksHandler := func(w http.ResponseWriter, r *http.Request) {
diff --git a/internal/user_route_test.go b/internal/user_route_test.go
@@ -26,13 +26,19 @@ func TestUsernameRoute404WhenMissing(t *testing.T) {
t.Fatalf("expected 404 for /nouser, got %d", resp.StatusCode)
}
- // Create a user and verify /alice returns 200 (serves SPA index)
- _, err = db.CreateUser(t.Context(), "alice", "pw")
- if err != nil {
- t.Fatalf("create user: %v", err)
- }
- resp2, _ := http.Get(srv.URL + "/alice")
- if resp2.StatusCode != http.StatusOK {
- t.Fatalf("expected 200 for /alice, got %d", resp2.StatusCode)
- }
+ // Create a user
+ _, err = db.CreateUser(t.Context(), "alice", "pw")
+ if err != nil {
+ t.Fatalf("create user: %v", err)
+ }
+ // Legacy /{username} route removed: should 404
+ resp2, _ := http.Get(srv.URL + "/alice")
+ if resp2.StatusCode != http.StatusNotFound {
+ t.Fatalf("expected 404 for /alice, got %d", resp2.StatusCode)
+ }
+ // New route /u:{username} should serve the page
+ resp3, _ := http.Get(srv.URL + "/u:alice")
+ if resp3.StatusCode != http.StatusOK {
+ t.Fatalf("expected 200 for /u:alice, got %d", resp3.StatusCode)
+ }
}