telegabber/xmpp/loginwizard.go

173 lines
4.4 KiB
Go

package xmpp
import (
"fmt"
"dev.narayana.im/narayana/telegabber/persistence"
"dev.narayana.im/narayana/telegabber/telegram"
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
log "github.com/sirupsen/logrus"
"gosrc.io/xmpp"
"gosrc.io/xmpp/stanza"
)
func loginWizardPayload(bare string, requestForm *stanza.Form, resource string, action string) (payload *stanza.Command, cancelSend bool, returnSession *telegram.Client) {
payload = &stanza.Command{
SessionId: "loginwizard",
Node: "loginwizard",
}
session, ok := sessions[bare]
if ok {
returnSession = session
var command string
if requestForm == nil {
session.StartLoginWizard(false)
cancelSend = true
} else if action == stanza.CommandActionComplete || action == stanza.CommandActionExecute {
command = "/finish"
} else {
if len(requestForm.Fields) != 1 {
setCommandPayloadError(payload, "Hey, don't tinker with the form!")
return
}
field := requestForm.Fields[0]
if field != nil {
if len(field.ValuesList) < 1 {
setCommandPayloadError(payload, "No value")
return
}
value := field.ValuesList[0]
switch field.Var {
case "login", "code", "password", "preset":
if field.Var == "preset" && value == "" {
command = "/pass"
} else {
command = fmt.Sprintf("/%v %v", field.Var, value)
}
case "muc":
fieldValue := persistence.NormalizeProperty(field.Var, value)
command = fmt.Sprintf("/config muc %v", fieldValue)
default:
setCommandPayloadError(payload, "Unknown field")
return
}
}
}
if command != "" {
session.StartLoginWizard(true)
response, success := session.ProcessTransportCommand(command, resource)
if !success {
setCommandPayloadError(payload, response)
session.StopLoginWizard()
return
}
cancelSend = true
}
} else {
setCommandPayloadError(payload, fmt.Sprintf("Session is not initialized, add the transport (%v) to contacts first", gateway.Jid.Bare()))
}
return
}
func sendLoginWizardResponse(component *xmpp.Component, answer *stanza.IQ, session *telegram.Client) {
payload := &stanza.Command{
SessionId: "loginwizard",
Node: "loginwizard",
}
nextStage := telegram.LoginStageLogin
if session != nil {
nextStage = session.GetLoginWizardNextStage()
}
log.Debugf("nextStage: %v", nextStage)
if nextStage == telegram.LoginStageNone || nextStage == telegram.LoginStageCancel {
setCommandPayloadError(payload, "Cancelled")
session.StopLoginWizard()
} else if nextStage == telegram.LoginStageSuccess {
payload.Status = stanza.CommandStatusCompleted
session.StopLoginWizard()
} else {
required := ""
var fieldType string
var finishAction bool
var options []stanza.Option
var note string
switch nextStage {
case telegram.LoginStagePreset:
fieldType = stanza.FieldTypeListSingle
finishAction = true
options = []stanza.Option{
stanza.Option{
ValuesList: []string{""},
},
stanza.Option{
Label: "Modern",
ValuesList: []string{"modern"},
},
stanza.Option{
Label: "Classic",
ValuesList: []string{"classic"},
},
}
note = "Do you want to use a config preset?\nModern enables brand new XMPP features,\nClassic targets legacy clients stuck in 00s."
case telegram.LoginStageMUC:
fieldType = stanza.FieldTypeBool
finishAction = true
value, err := session.Session.Get("muc")
if err != nil {
log.Error("Achtung! Programming error in retrieving MUC config option")
value = "false"
}
options = append(options, stanza.Option{
ValuesList: []string{value},
})
note = "Enable MUCs? Telegabber still supports the legacy group-to-PM mapping too."
}
form := stanza.Form{
Type: stanza.FormTypeForm,
Title: "Login Wizard",
Fields: []*stanza.Field{
&stanza.Field{
Var: string(nextStage),
Label: string(nextStage),
Required: &required,
Type: fieldType,
Options: options,
},
},
}
payload.Status = stanza.CommandStatusExecuting
payload.CommandElements = append(payload.CommandElements, &form)
actions := stanza.Actions{
Next: &struct{}{},
}
if finishAction {
actions.Complete = &struct{}{}
}
payload.CommandElements = append(payload.CommandElements, &actions)
if note != "" {
payload.CommandElements = append(payload.CommandElements, &stanza.Note{
Text: note,
Type: stanza.CommandNoteTypeInfo,
})
}
}
answer.Payload = payload
gateway.ResumableSend(component, answer)
}