package main import ( crand "crypto/rand" "encoding/hex" "html/template" "net/http" "time" ) func Must[T any](value T, err error) T { if err != nil { panic(err) } return value } func generateRandomID(length int) (string, error) { data := make([]byte, 32) if _, err := crand.Read(data); err != nil { return "", err } return hex.EncodeToString(data), nil } func GetSession(w http.ResponseWriter, r *http.Request) (*Session, error) { cookie, err := r.Cookie("session") if err != nil { return makeNewSession(w) } session := GetSessionByID(cookie.Value) if session == nil { return makeNewSession(w) } // update cookie expiration date session.ExpirationDate = time.Now().AddDate(1, 0, 0) if err := UpdateSession(session); err != nil { return nil, err } http.SetCookie(w, &http.Cookie{ Name: "session", Value: session.ID, Expires: session.ExpirationDate, Secure: true, HttpOnly: true, }) return session, nil } func makeNewSession(w http.ResponseWriter) (*Session, error) { session, err := NewSession() if err != nil { return nil, err } if err := InsertSession(session); err != nil { return nil, err } // insert default bookmarks for _, bookmark := range DefaultBookmarks() { bookmark.SessionID = session.ID if err := InsertBookmark(&bookmark); err != nil { return nil, err } } // insert default settings settings := DefaultSettings() settings.SessionID = session.ID if err := InsertSettings(settings); err != nil { return nil, err } http.SetCookie(w, &http.Cookie{ Name: "session", Value: session.ID, Expires: session.ExpirationDate, Secure: true, HttpOnly: true, }) return session, nil } var tmplFuncs = template.FuncMap{ "js": func(s string) template.JS { return template.JS(s) }, "jss": func(s string) template.JSStr { return template.JSStr(s) }, "css": func(s string) template.CSS { return template.CSS(s) }, "attr": func(s string) template.HTMLAttr { return template.HTMLAttr(s) }, "safe": func(s string) template.HTML { return template.HTML(s) }, "url": func(s string) template.URL { return template.URL(s) }, }