commit 827f058496f980b3d6c00922da5acb015544e697
parent 1bea21100843fda05707fad0b7a69977f4bd4654
Author: David Eisinger <[email protected]>
Date: Tue, 7 Oct 2025 15:41:01 -0400
Embded API Key in bookmarklet
Diffstat:
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("&", "&", "<", "<", ">", ">")
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>