marky

Lightweight bookmarking + plaintext archive
Log | Files | Refs | README | LICENSE

commit 827f058496f980b3d6c00922da5acb015544e697
parent 1bea21100843fda05707fad0b7a69977f4bd4654
Author: David Eisinger <[email protected]>
Date:   Tue,  7 Oct 2025 15:41:01 -0400

Embded API Key in bookmarklet

Diffstat:
Minternal/api.go | 47+++++++++++++++++++++++++++++++++++------------
Minternal/web/bookmarklet.html | 2+-
2 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/internal/api.go b/internal/api.go @@ -98,15 +98,14 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } - uid, ok := CurrentUserID(r) - if !ok { - http.Error(w, "unauthorized", http.StatusUnauthorized) - return - } - user, err := db.GetUserByID(r.Context(), uid) - if err != nil || user == nil { - http.Error(w, "unauthorized", http.StatusUnauthorized) - return + uid, hasSession := CurrentUserID(r) + var user *User + var err error + if hasSession { + if user, err = db.GetUserByID(r.Context(), uid); err != nil { + user = nil + hasSession = false + } } // Resolve origin to use in links opened by the bookmarklet scheme := "http" @@ -115,7 +114,11 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) { } origin := scheme + "://" + r.Host // Fetch API token (if present) for interpolation - token, present, err := db.GetAPIToken(r.Context(), uid) + var token string + var present bool + if hasSession { + token, present, err = db.GetAPIToken(r.Context(), uid) + } if err != nil { log.Printf("get api token error: %v", err) } @@ -125,6 +128,10 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) { // Helpers for embedding JSON strings into HTML templates enc := func(s string) string { b, _ := json.Marshal(s); return string(b) } if pageURL == "" { + if !hasSession || user == nil { + http.Error(w, "unauthorized", http.StatusUnauthorized) + return + } // Installer page: assemble from template with shared header w.Header().Set("Content-Type", "text/html; charset=utf-8") headTpl, err := fs.ReadFile(webAssets, "web/header.html") @@ -141,6 +148,12 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) { page := string(pageTpl) page = strings.ReplaceAll(page, "{{HEADER}}", headerHTML) page = strings.ReplaceAll(page, "{{ORIGIN}}", origin) + // Add auth query parameters for incognito usage (when token present) + auth := "" + if present { + auth = "&user=" + url.QueryEscape(user.Username) + "&tok=" + url.QueryEscape(token) + } + page = strings.ReplaceAll(page, "{{AUTH}}", auth) _, _ = w.Write([]byte(page)) return } @@ -156,11 +169,21 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) { r := strings.NewReplacer("&", "&amp;", "<", "&lt;", ">", "&gt;") return r.Replace(s) } + // Prefer token from query string for incognito usage + qTok := q.Get("tok") + qUser := q.Get("user") jsToken := "null" - if present { + if strings.TrimSpace(qTok) != "" { + jsToken = enc(qTok) + } else if present { jsToken = enc(token) } - jsUser := enc(user.Username) + jsUser := "null" + if strings.TrimSpace(qUser) != "" { + jsUser = enc(qUser) + } else if user != nil { + jsUser = enc(user.Username) + } w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprintf(w, `<!doctype html> <html lang="en"> diff --git a/internal/web/bookmarklet.html b/internal/web/bookmarklet.html @@ -17,7 +17,7 @@ <h2>Save to Marky</h2> <p>Drag this to your bookmarks bar:</p> <p> - <a class="btn" href="javascript:(function(){try{var d=document;var s=encodeURIComponent;var u=location.href;var t=document.title;var sel='';if(d.getSelection){sel=d.getSelection().toString()}else if(window.getSelection){sel=window.getSelection().toString()}else if(d.selection){sel=d.selection.createRange().text}var win=window.open('{{ORIGIN}}/bookmarklet?u='+s(u)+'&t='+s(t)+'&d='+s(sel),'marky','width=520,height=520');if(win){win.focus()}}catch(e){alert('Could not open Marky: '+e)}})();">Save to Marky</a> + <a class="btn" href="javascript:(function(){try{var d=document;var s=encodeURIComponent;var u=location.href;var t=document.title;var sel='';if(d.getSelection){sel=d.getSelection().toString()}else if(window.getSelection){sel=window.getSelection().toString()}else if(d.selection){sel=d.selection.createRange().text}var win=window.open('{{ORIGIN}}/bookmarklet?u='+s(u)+'&t='+s(t)+'&d='+s(sel)+'{{AUTH}}','marky','width=520,height=520');if(win){win.focus()}}catch(e){alert('Could not open Marky: '+e)}})();">Save to Marky</a> </p> <div class="notice"> <p>When clicked on any page, this opens a small form prefilled with the page URL and title. On submit, it saves to your Marky account.</p>