package middleware import ( "context" "net/http" "github.com/gin-gonic/gin" ) // ParentResolver is the minimum the middleware needs from the parent // service. Defined as interface so handlers can pass their own service // without import cycles. type ParentResolver interface { ParentFromSession(ctx context.Context, token string) (parent interface{}, err error) } // ParentSessionCookieName is the name of the HttpOnly cookie that carries // the parent's session token after redeem. Exported so handlers can set it. const ParentSessionCookieName = "bp_parent_session" // ParentSessionMiddleware reads the parent session cookie and resolves it // to a parent_account. Stores parent_id (string) in the Gin context for // downstream handlers. Aborts with 401 if the cookie is missing or the // session expired. func ParentSessionMiddleware(resolve func(ctx context.Context, token string) (string, string, string, error)) gin.HandlerFunc { return func(c *gin.Context) { token, err := c.Cookie(ParentSessionCookieName) if err != nil || token == "" { c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Parent session required"}) return } parentID, email, lang, err := resolve(c.Request.Context(), token) if err != nil { c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid or expired session"}) return } c.Set("parent_id", parentID) c.Set("parent_email", email) c.Set("parent_language", lang) c.Next() } }