package middleware import ( "context" "log" "maxwarden/config" "maxwarden/constants" "maxwarden/security" "net/http" "time" ) type sessionKey struct{} func LoadSession(h http.HandlerFunc) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var sessionMap map[string]interface{} sessionCookie, err := r.Cookie(constants.SESSION_COOKIE_NAME) if err == nil { decryptMap, _ := security.DecryptData[map[string]interface{}]( []byte(security.DecodeBase58(sessionCookie.Value)), config.GetConfig().IdentityPrivateKey, ) sessionMap = *decryptMap } if sessionMap == nil { sessionMap = make(map[string]interface{}) } ctx := context.WithValue(r.Context(), sessionKey{}, sessionMap) h.ServeHTTP(w, r.WithContext(ctx)) }) } func GetSession(r *http.Request) map[string]interface{} { session := r.Context().Value(sessionKey{}).(map[string]interface{}) return session } func PutSessionCookie(w http.ResponseWriter, r *http.Request, session map[string]interface{}) { cookies := r.Cookies() // calculate total bytes used by other cookies var totalBytes int for _, cookie := range cookies { if cookie.Name == constants.SESSION_COOKIE_NAME { continue } else { totalBytes += len(cookie.Value) } } sessionData, err := security.EncryptData(&session, config.GetConfig().IdentityPrivateKey) if err != nil { return } length := len(sessionData) + 8 if length+totalBytes > 4096 { log.Println("Attempt to generate cookie exceeding size limit for this domain") return } httpCookie := &http.Cookie{ Name: constants.SESSION_COOKIE_NAME, Value: security.EncodeBase58(sessionData), HttpOnly: true, Secure: r.URL.Scheme == "https", Path: "/", SameSite: http.SameSiteStrictMode, } http.SetCookie(w, httpCookie) } func DeleteSessionCookie(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, &http.Cookie{ Name: constants.SESSION_COOKIE_NAME, MaxAge: -1, Expires: time.Now().Add(-100 * time.Hour), Path: "/", }) }