commit a8dd728f2e9a1be1ee223da5d646459ec7bcec98
parent 48502626fcbdc6ecd5b69b6073848766be2ef46e
Author: David Eisinger <[email protected]>
Date: Thu, 9 Oct 2025 22:07:15 -0400
Remove /me endpoint
Diffstat:
4 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/README.md b/README.md
@@ -38,7 +38,6 @@ Marky supports session cookies (for the web UI) and API tokens (for scripts, fee
- POST `/signup` { username, password }
- POST `/login` { username, password }
- POST `/logout`
- - GET `/me` returns `{ username }` when authenticated
- API tokens: per-user credential used with HTTP Basic, header, or query param
- GET `/api/token` → `{ present: true|false }`
diff --git a/internal/api.go b/internal/api.go
@@ -87,16 +87,6 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) {
ClearSession(w)
w.WriteHeader(http.StatusNoContent)
})
- mux.HandleFunc("/me", func(w http.ResponseWriter, r *http.Request) {
- if uid, ok := userIDFromRequest(r, db); ok {
- if u, err := db.GetUserByID(r.Context(), uid); err == nil && u != nil {
- w.Header().Set("Content-Type", "application/json")
- _ = json.NewEncoder(w).Encode(map[string]any{"username": u.Username})
- return
- }
- }
- http.Error(w, "unauthorized", http.StatusUnauthorized)
- })
// Bookmarklet generator and popup form
mux.HandleFunc("/bookmarklet", func(w http.ResponseWriter, r *http.Request) {
@@ -351,7 +341,7 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) {
return
}
if html, err := RenderPage("settings.html", cfg); err == nil {
- // Embed API token directly for settings hydration
+ // Embed API token and current username for hydration
if tok, _, err := db.GetAPIToken(r.Context(), uid); err == nil {
inject := []byte("<script>window.MARKY_TOKEN=" + strconv.Quote(tok) + "</script>\n")
marker := []byte("<script src=\"/app.js\"></script>")
@@ -363,6 +353,17 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) {
html = out
}
}
+ if u, err := db.GetUserByID(r.Context(), uid); err == nil && u != nil {
+ inject := []byte("<script>window.MARKY_ME=" + strconv.Quote(u.Username) + "</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
+ }
+ }
html = applyCacheBust(html)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_, _ = w.Write(html)
@@ -390,6 +391,20 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) {
}
if u, err := db.GetUserByUsername(r.Context(), uname); err == nil && u != nil {
if html, err := RenderPage("user.html", cfg); err == nil {
+ // Embed current username (if logged in)
+ if uid, ok := userIDFromRequest(r, db); ok && uid > 0 {
+ if cu, err := db.GetUserByID(r.Context(), uid); err == nil && cu != nil {
+ meInject := []byte("<script>window.MARKY_ME=" + strconv.Quote(cu.Username) + "</script>\n")
+ marker := []byte("<script src=\"/app.js\"></script>")
+ if i := bytes.Index(html, marker); i >= 0 {
+ out := make([]byte, 0, len(html)+len(meInject))
+ out = append(out, html[:i]...)
+ out = append(out, meInject...)
+ out = append(out, html[i:]...)
+ html = out
+ }
+ }
+ }
// Set <title> to "{username} | Marky" by replacing inner text only
if ti := bytes.Index(html, []byte("<title>")); ti >= 0 {
if tj := bytes.Index(html[ti:], []byte("</title>")); tj > 0 {
diff --git a/internal/api_auth_test.go b/internal/api_auth_test.go
@@ -9,7 +9,7 @@ import (
"testing"
)
-func TestSignupLoginLogoutMe(t *testing.T) {
+func TestSignupLoginLogoutSession(t *testing.T) {
t.Parallel()
db, err := OpenAtPath(t.Context(), t.TempDir()+"/authz.db")
if err != nil {
@@ -23,10 +23,10 @@ func TestSignupLoginLogoutMe(t *testing.T) {
jar, _ := cookiejar.New(nil)
client := &http.Client{Jar: jar}
- // /me unauth
- resp, _ := http.Get(srv.URL + "/me")
+ // /bookmarks unauth should be 401
+ resp, _ := http.Get(srv.URL + "/bookmarks")
if resp.StatusCode != http.StatusUnauthorized {
- t.Fatalf("/me unauth got %d", resp.StatusCode)
+ t.Fatalf("/bookmarks unauth got %d", resp.StatusCode)
}
// signup
@@ -39,10 +39,10 @@ func TestSignupLoginLogoutMe(t *testing.T) {
}
rs.Body.Close()
- // /me auth
- r2, _ := client.Get(srv.URL + "/me")
+ // /bookmarks auth should be 200 (empty list)
+ r2, _ := client.Get(srv.URL + "/bookmarks")
if r2.StatusCode != http.StatusOK {
- t.Fatalf("/me auth %d", r2.StatusCode)
+ t.Fatalf("/bookmarks auth %d", r2.StatusCode)
}
r2.Body.Close()
@@ -54,10 +54,10 @@ func TestSignupLoginLogoutMe(t *testing.T) {
}
rs3.Body.Close()
- // /me again
- r4, _ := client.Get(srv.URL + "/me")
+ // /bookmarks after logout should be 401 again
+ r4, _ := client.Get(srv.URL + "/bookmarks")
if r4.StatusCode != http.StatusUnauthorized {
- t.Fatalf("/me after logout %d", r4.StatusCode)
+ t.Fatalf("/bookmarks after logout %d", r4.StatusCode)
}
r4.Body.Close()
}
diff --git a/internal/web/app.js b/internal/web/app.js
@@ -23,19 +23,13 @@ createApp({
},
methods: {
async initView() {
- // Determine logged-in user
- try {
- const res = await fetch('/me');
- if (res.ok) this.me = await res.json();
- } catch {}
+ // Determine logged-in user from server-embedded data
+ if (window.MARKY_ME) this.me = { username: window.MARKY_ME };
const p = location.pathname.replace(/^\/+/, '');
const first = p.split('/')[0] || '';
// Root: show login/signup or redirect to user page
if (!first) {
- if (this.me && this.me.username) {
- location.replace('/u:' + this.me.username);
- return;
- }
+ // Server redirects logged-in users to /u:{username}; render login/signup otherwise
this.view = 'login';
return;
}