mirror of
https://github.com/oarkflow/mq.git
synced 2025-10-22 04:49:21 +08:00
update
This commit is contained in:
10
dag/dag.go
10
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)
|
||||
}
|
||||
|
@@ -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"))
|
||||
|
24
dag/utils.go
24
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
|
||||
}
|
||||
|
143
examples/form.go
143
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 := `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Phone Processing System - Already Authenticated</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.auth-container {
|
||||
background: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
text-align: center;
|
||||
}
|
||||
.auth-header {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.auth-header h1 {
|
||||
color: #333;
|
||||
margin: 0;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
.auth-header p {
|
||||
color: #666;
|
||||
margin: 0.5rem 0 0 0;
|
||||
}
|
||||
.success-icon {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.user-info {
|
||||
background: #f8f9fa;
|
||||
padding: 1rem;
|
||||
border-radius: 5px;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.user-info p {
|
||||
margin: 0.5rem 0;
|
||||
color: #333;
|
||||
}
|
||||
.countdown {
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
color: #667eea;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="auth-container">
|
||||
<div class="auth-header">
|
||||
<div class="success-icon">✅</div>
|
||||
<h1>Already Authenticated</h1>
|
||||
<p>Welcome back!</p>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<p><strong>Username:</strong> ` + fmt.Sprintf("%v", sess.Get("username")) + `</p>
|
||||
<p><strong>Role:</strong> ` + fmt.Sprintf("%v", sess.Get("user_role")) + `</p>
|
||||
</div>
|
||||
<div class="countdown">
|
||||
Redirecting in <span id="countdown">1</span> second...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="autoSubmitForm" method="post" action="/process?task_id=` + fmt.Sprintf("%v", ctx.Value("task_id")) + `&next=true" style="display: none;">
|
||||
<input type="hidden" name="authenticated" value="true">
|
||||
<input type="hidden" name="username" value="` + fmt.Sprintf("%v", sess.Get("username")) + `">
|
||||
<input type="hidden" name="user_role" value="` + fmt.Sprintf("%v", sess.Get("user_role")) + `">
|
||||
<input type="hidden" name="auth_token" value="` + fmt.Sprintf("%v", sess.Get("auth_token")) + `">
|
||||
<input type="hidden" name="skip_login" value="true">
|
||||
</form>
|
||||
|
||||
<script>
|
||||
let countdown = 1;
|
||||
const countdownElement = document.getElementById('countdown');
|
||||
|
||||
const timer = setInterval(() => {
|
||||
countdown--;
|
||||
countdownElement.textContent = countdown;
|
||||
|
||||
if (countdown <= 0) {
|
||||
clearInterval(timer);
|
||||
document.getElementById('autoSubmitForm').submit();
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
ctx = context.WithValue(ctx, consts.ContentType, consts.TypeHtml)
|
||||
resultData := map[string]any{
|
||||
"html_content": htmlContent,
|
||||
"step": "authenticated",
|
||||
}
|
||||
resultPayload, _ := json.Marshal(resultData)
|
||||
return mq.Result{
|
||||
Payload: resultPayload,
|
||||
Ctx: ctx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is a form submission
|
||||
var inputData map[string]any
|
||||
if len(task.Payload) > 0 {
|
||||
@@ -264,6 +384,20 @@ func (p *VerifyCredentials) ProcessTask(ctx context.Context, task *mq.Task) mq.R
|
||||
return mq.Result{Error: fmt.Errorf("VerifyCredentials Error: %s", err.Error()), Ctx: ctx}
|
||||
}
|
||||
|
||||
// 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, restore session data
|
||||
data["authenticated"] = true
|
||||
data["username"] = sess.Get("username")
|
||||
data["user_role"] = sess.Get("user_role")
|
||||
data["auth_token"] = sess.Get("auth_token")
|
||||
delete(data, "html_content")
|
||||
updatedPayload, _ := json.Marshal(data)
|
||||
return mq.Result{Payload: updatedPayload, Ctx: ctx}
|
||||
}
|
||||
}
|
||||
|
||||
username, _ := data["username"].(string)
|
||||
password, _ := data["password"].(string)
|
||||
|
||||
@@ -302,6 +436,15 @@ func (p *GenerateToken) ProcessTask(ctx context.Context, task *mq.Task) mq.Resul
|
||||
data["auth_token"] = "jwt_token_123456789"
|
||||
data["token_expires"] = "2025-09-19T13:00:00Z"
|
||||
data["login_success"] = true
|
||||
|
||||
// Store authentication in session
|
||||
if sess, ok := ctx.Value("session").(*session.Session); ok {
|
||||
sess.Set("authenticated", true)
|
||||
sess.Set("username", data["username"])
|
||||
sess.Set("user_role", data["user_role"])
|
||||
sess.Set("auth_token", data["auth_token"])
|
||||
sess.Save()
|
||||
}
|
||||
}
|
||||
|
||||
delete(data, "html_content")
|
||||
|
Reference in New Issue
Block a user