diff --git a/dag/dag.go b/dag/dag.go index cd79dd3..016512e 100644 --- a/dag/dag.go +++ b/dag/dag.go @@ -11,6 +11,7 @@ import ( "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/recover" + "github.com/gofiber/fiber/v2/middleware/session" "github.com/oarkflow/form" "github.com/oarkflow/json" "golang.org/x/time/rate" @@ -134,6 +135,9 @@ type DAG struct { // Task storage for persistence taskStorage dagstorage.TaskStorage + + // Session store for authentication + sessionStore *session.Store } // SetPreProcessHook configures a function to be called before each node is processed. @@ -1015,6 +1019,12 @@ func (tm *DAG) Start(ctx context.Context, addr string) error { app.Use(recover.New(recover.Config{ EnableStackTrace: true, })) + if tm.sessionStore == nil { + tm.sessionStore = session.New(session.Config{ + CookieHTTPOnly: true, + Expiration: 24 * time.Hour, + }) + } tm.Handlers(app, "/") return app.Listen(addr) } diff --git a/dag/fiber_api.go b/dag/fiber_api.go index 18fa890..8a9623c 100644 --- a/dag/fiber_api.go +++ b/dag/fiber_api.go @@ -36,6 +36,12 @@ func (tm *DAG) RenderFiber(c *fiber.Ctx) error { accept := c.Get("Accept") userCtx := form.UserContext(ctx) ctx = context.WithValue(ctx, "method", c.Method()) + if tm.sessionStore != nil { + sess, err := tm.sessionStore.Get(c) + if err == nil { + ctx = context.WithValue(ctx, "session", sess) + } + } if c.Method() == fiber.MethodGet && userCtx.Get("task_id") != "" { manager, ok := tm.taskManager.Get(userCtx.Get("task_id")) diff --git a/dag/utils.go b/dag/utils.go index 36d52f0..bd2a6d9 100644 --- a/dag/utils.go +++ b/dag/utils.go @@ -6,6 +6,7 @@ import ( "sync" "time" + "github.com/gofiber/fiber/v2/middleware/session" "github.com/oarkflow/json" "github.com/oarkflow/mq" dagstorage "github.com/oarkflow/mq/dag/storage" @@ -600,3 +601,26 @@ func (h *ActivityAlertHandler) HandleAlert(alert Alert) error { } return nil } + +func CanSession(ctx context.Context, key string) bool { + sess, ok := ctx.Value("session").(*session.Session) + if !ok || sess == nil { + return false + } + if authenticated, exists := sess.Get(key).(bool); exists && authenticated { + return true + } + return false +} + +func GetSession(ctx context.Context, key string) (any, bool) { + sess, ok := ctx.Value("session").(*session.Session) + if !ok || sess == nil { + return nil, false + } + value := sess.Get(key) + if value != nil { + return value, true + } + return nil, false +} diff --git a/examples/form.go b/examples/form.go index c5cfca3..33fc848 100644 --- a/examples/form.go +++ b/examples/form.go @@ -12,6 +12,7 @@ import ( "github.com/oarkflow/mq/dag" "github.com/oarkflow/mq/utils" + "github.com/gofiber/fiber/v2/middleware/session" "github.com/oarkflow/jet" "github.com/oarkflow/mq" @@ -70,6 +71,125 @@ type LoginPage struct { } func (p *LoginPage) ProcessTask(ctx context.Context, task *mq.Task) mq.Result { + // Check if user is already authenticated via session + if sess, ok := ctx.Value("session").(*session.Session); ok { + if authenticated, exists := sess.Get("authenticated").(bool); exists && authenticated { + // User is already authenticated, show auto-submit page + htmlContent := ` + + +
+ + +Welcome back!
+