mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-04 19:57:07 +00:00
Login Wizard
This commit is contained in:
parent
0368b8cad8
commit
85846346d1
7 changed files with 315 additions and 58 deletions
|
|
@ -278,7 +278,7 @@ func PropertyType(key string) byte {
|
|||
case "timezone":
|
||||
return PropertyTypeString
|
||||
case "keeponline", "rawmessages", "asciiarrows", "oobmode", "carbons", "hideids",
|
||||
"receipts", "nativeedits", "ignoregroupdeletions":
|
||||
"receipts", "nativeedits", "ignoregroupdeletions":
|
||||
return PropertyTypeBool
|
||||
}
|
||||
return PropertyTypeUnknown
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ type Client struct {
|
|||
cache *cache.Cache
|
||||
online bool
|
||||
|
||||
loginWizard *loginWizardMetadata
|
||||
|
||||
lastAuthorizationStateType string
|
||||
|
||||
outbox map[string]string
|
||||
editOutbox map[string]string
|
||||
|
||||
|
|
@ -75,6 +79,15 @@ type clientLocks struct {
|
|||
|
||||
authorizerReadLock sync.Mutex
|
||||
authorizerWriteLock sync.Mutex
|
||||
|
||||
loginWizardReadLock sync.Mutex
|
||||
loginWizardWriteLock sync.Mutex
|
||||
}
|
||||
|
||||
type loginWizardMetadata struct {
|
||||
nextStage chan string
|
||||
chanBusy bool
|
||||
commandSent bool
|
||||
}
|
||||
|
||||
// NewClient instantiates a Telegram App
|
||||
|
|
|
|||
|
|
@ -51,22 +51,22 @@ var permissionsMember = client.ChatPermissions{
|
|||
var permissionsReadonly = client.ChatPermissions{}
|
||||
|
||||
var transportCommands = map[string]command{
|
||||
"help": command{0, []string{}, "help", nil},
|
||||
"login": command{1, []string{"phone"}, "sign in", nil},
|
||||
"logout": command{0, []string{}, "sign out", nil},
|
||||
"cancelauth": command{0, []string{}, "quit the signin wizard", nil},
|
||||
"code": command{1, []string{"xxxxx"}, "check one-time code", nil},
|
||||
"password": command{1, []string{"********"}, "check 2fa password", nil},
|
||||
"setusername": command{0, []string{"@username"}, "update @username", nil},
|
||||
"setname": command{1, []string{"first", "last"}, "update name", nil},
|
||||
"setbio": command{0, []string{"Lorem ipsum"}, "update about", nil},
|
||||
"setpassword": command{0, []string{"old", "new"}, "set or remove password", nil},
|
||||
"config": command{0, []string{"param", "value"}, "view or update configuration options", nil},
|
||||
"report": command{2, []string{"chat", "comment"}, "report a chat by id or @username", nil},
|
||||
"add": command{1, []string{"@username"}, "add @username to your chat list", nil},
|
||||
"join": command{1, []string{"https://t.me/invite_link"}, "join to chat via invite link or @publicname", nil},
|
||||
"supergroup": command{1, []string{"title", "description"}, "create new supergroup «title» with «description»", nil},
|
||||
"channel": command{1, []string{"title", "description"}, "create new channel «title» with «description»", nil},
|
||||
"help": command{0, []string{}, "help", false, nil},
|
||||
"login": command{1, []string{"phone"}, "sign in", false, nil},
|
||||
"logout": command{0, []string{}, "sign out", true, nil},
|
||||
"cancelauth": command{0, []string{}, "quit the signin wizard", false, nil},
|
||||
"code": command{1, []string{"xxxxx"}, "check one-time code", false, nil},
|
||||
"password": command{1, []string{"********"}, "check 2fa password", false, nil},
|
||||
"setusername": command{0, []string{"@username"}, "update @username", true, nil},
|
||||
"setname": command{1, []string{"first", "last"}, "update name", true, nil},
|
||||
"setbio": command{0, []string{"Lorem ipsum"}, "update about", true, nil},
|
||||
"setpassword": command{0, []string{"old", "new"}, "set or remove password", true, nil},
|
||||
"config": command{0, []string{"param", "value"}, "view or update configuration options", false, nil},
|
||||
"report": command{2, []string{"chat", "comment"}, "report a chat by id or @username", true, nil},
|
||||
"add": command{1, []string{"@username"}, "add @username to your chat list", true, nil},
|
||||
"join": command{1, []string{"https://t.me/invite_link"}, "join to chat via invite link or @publicname", true, nil},
|
||||
"supergroup": command{1, []string{"title", "description"}, "create new supergroup «title» with «description»", true, nil},
|
||||
"channel": command{1, []string{"title", "description"}, "create new channel «title» with «description»", true, nil},
|
||||
}
|
||||
|
||||
var notForGroups = []ChatType{ChatTypeBasicGroup, ChatTypeSupergroup, ChatTypeChannel}
|
||||
|
|
@ -75,37 +75,37 @@ var notForPMAndBasic = []ChatType{ChatTypePrivate, ChatTypeSecret, ChatTypeBasic
|
|||
var onlyForSecret = []ChatType{ChatTypePrivate, ChatTypeBasicGroup, ChatTypeSupergroup, ChatTypeChannel}
|
||||
|
||||
var chatCommands = map[string]command{
|
||||
"help": command{0, []string{}, "help", nil},
|
||||
"d": command{0, []string{"n"}, "delete your last message(s)", nil},
|
||||
"s": command{1, []string{"edited message"}, "edit your last message", nil},
|
||||
"silent": command{1, []string{"message"}, "send a message without sound", nil},
|
||||
"schedule": command{2, []string{"{online | 2006-01-02T15:04:05 | 15:04:05}", "message"}, "schedules a message either to timestamp or to whenever the user goes online", nil},
|
||||
"forward": command{2, []string{"message_id", "target_chat"}, "forwards a message", nil},
|
||||
"vcard": command{0, []string{}, "print vCard as text", nil},
|
||||
"add": command{1, []string{"@username"}, "add @username to your chat list", nil},
|
||||
"join": command{1, []string{"https://t.me/invite_link"}, "join to chat via invite link or @publicname", nil},
|
||||
"group": command{1, []string{"title"}, "create groupchat «title» with current user", ¬ForGroups},
|
||||
"supergroup": command{1, []string{"title", "description"}, "create new supergroup «title» with «description»", nil},
|
||||
"channel": command{1, []string{"title", "description"}, "create new channel «title» with «description»", nil},
|
||||
"secret": command{0, []string{}, "create secretchat with current user", ¬ForGroups},
|
||||
"search": command{0, []string{"string", "[limit]"}, "search <string> in current chat", nil},
|
||||
"history": command{0, []string{"limit"}, "get last [limit] messages from current chat", nil},
|
||||
"block": command{0, []string{}, "blacklist current user", ¬ForGroups},
|
||||
"unblock": command{0, []string{}, "unblacklist current user", ¬ForGroups},
|
||||
"invite": command{1, []string{"id or @username"}, "add user to current chat", ¬ForPM},
|
||||
"link": command{0, []string{}, "get invite link for current chat", ¬ForPM},
|
||||
"kick": command{1, []string{"id or @username"}, "remove user from current chat", ¬ForPM},
|
||||
"mute": command{0, []string{"id or @username", "hours"}, "mute the whole chat or a user in current chat", ¬ForPMAndBasic},
|
||||
"unmute": command{0, []string{"id or @username"}, "unmute the whole chat or a user in the current chat", ¬ForPMAndBasic},
|
||||
"ban": command{1, []string{"id or @username", "hours"}, "restrict @username from current chat for [hours] or forever", ¬ForPM},
|
||||
"unban": command{1, []string{"id or @username"}, "unbans @username in current chat (and devotes from admins)", ¬ForPM},
|
||||
"promote": command{1, []string{"id or @username", "title"}, "promote user to admin in current chat", ¬ForPM},
|
||||
"leave": command{0, []string{}, "leave current chat", ¬ForPM},
|
||||
"leave!": command{0, []string{}, "leave current chat (for owners)", ¬ForPM},
|
||||
"ttl": command{0, []string{"seconds"}, "set secret chat messages TTL before self-destroying", &onlyForSecret},
|
||||
"close": command{0, []string{}, "close current secret chat", &onlyForSecret},
|
||||
"delete": command{0, []string{}, "delete current chat from chat list", nil},
|
||||
"members": command{0, []string{"query"}, "search members [by optional query] in current chat (requires admin rights)", nil},
|
||||
"help": command{0, []string{}, "help", false, nil},
|
||||
"d": command{0, []string{"n"}, "delete your last message(s)", true, nil},
|
||||
"s": command{1, []string{"edited message"}, "edit your last message", true, nil},
|
||||
"silent": command{1, []string{"message"}, "send a message without sound", true, nil},
|
||||
"schedule": command{2, []string{"{online | 2006-01-02T15:04:05 | 15:04:05}", "message"}, "schedules a message either to timestamp or to whenever the user goes online", true, nil},
|
||||
"forward": command{2, []string{"message_id", "target_chat"}, "forwards a message", true, nil},
|
||||
"vcard": command{0, []string{}, "print vCard as text", true, nil},
|
||||
"add": command{1, []string{"@username"}, "add @username to your chat list", true, nil},
|
||||
"join": command{1, []string{"https://t.me/invite_link"}, "join to chat via invite link or @publicname", true, nil},
|
||||
"group": command{1, []string{"title"}, "create groupchat «title» with current user", true, ¬ForGroups},
|
||||
"supergroup": command{1, []string{"title", "description"}, "create new supergroup «title» with «description»", true, nil},
|
||||
"channel": command{1, []string{"title", "description"}, "create new channel «title» with «description»", true, nil},
|
||||
"secret": command{0, []string{}, "create secretchat with current user", true, ¬ForGroups},
|
||||
"search": command{0, []string{"string", "[limit]"}, "search <string> in current chat", true, nil},
|
||||
"history": command{0, []string{"limit"}, "get last [limit] messages from current chat", true, nil},
|
||||
"block": command{0, []string{}, "blacklist current user", true, ¬ForGroups},
|
||||
"unblock": command{0, []string{}, "unblacklist current user", true, ¬ForGroups},
|
||||
"invite": command{1, []string{"id or @username"}, "add user to current chat", true, ¬ForPM},
|
||||
"link": command{0, []string{}, "get invite link for current chat", true, ¬ForPM},
|
||||
"kick": command{1, []string{"id or @username"}, "remove user from current chat", true, ¬ForPM},
|
||||
"mute": command{0, []string{"id or @username", "hours"}, "mute the whole chat or a user in current chat", true, ¬ForPMAndBasic},
|
||||
"unmute": command{0, []string{"id or @username"}, "unmute the whole chat or a user in the current chat", true, ¬ForPMAndBasic},
|
||||
"ban": command{1, []string{"id or @username", "hours"}, "restrict @username from current chat for [hours] or forever", true, ¬ForPM},
|
||||
"unban": command{1, []string{"id or @username"}, "unbans @username in current chat (and devotes from admins)", true, ¬ForPM},
|
||||
"promote": command{1, []string{"id or @username", "title"}, "promote user to admin in current chat", true, ¬ForPM},
|
||||
"leave": command{0, []string{}, "leave current chat", true, ¬ForPM},
|
||||
"leave!": command{0, []string{}, "leave current chat (for owners)", true, ¬ForPM},
|
||||
"ttl": command{0, []string{"seconds"}, "set secret chat messages TTL before self-destroying", true, &onlyForSecret},
|
||||
"close": command{0, []string{}, "close current secret chat", true, &onlyForSecret},
|
||||
"delete": command{0, []string{}, "delete current chat from chat list", true, nil},
|
||||
"members": command{0, []string{"query"}, "search members [by optional query] in current chat (requires admin rights)", true, nil},
|
||||
}
|
||||
|
||||
var transportConfigurationOptions = map[string]configurationOption{
|
||||
|
|
@ -125,6 +125,7 @@ type command struct {
|
|||
RequiredArgs int
|
||||
Arguments []string
|
||||
Description string
|
||||
LoginOnly bool
|
||||
NotFor *[]ChatType
|
||||
}
|
||||
type configurationOption struct {
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ func (c *Client) Connect(resource string) error {
|
|||
tdlibClient, err := client.NewClient(c.authorizer, c.options...)
|
||||
if err != nil {
|
||||
c.locks.authorizationReady.Unlock()
|
||||
c.wizardStageOrPrompt("cancel", "")
|
||||
return errors.Wrap(err, "Couldn't initialize a Telegram client instance")
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +138,8 @@ func (c *Client) Connect(resource string) error {
|
|||
// stage 3: if a client is succesfully created, AuthorizationStateReady is already reached
|
||||
log.Warn("Authorization successful!")
|
||||
|
||||
c.wizardStageOrPrompt("success", "")
|
||||
|
||||
c.me, err = c.client.GetMe()
|
||||
if err != nil {
|
||||
log.Error("Could not retrieve me info")
|
||||
|
|
@ -255,6 +258,8 @@ func (c *Client) interactor() {
|
|||
log.Infof("Telegram authorization state: %#v", stateType)
|
||||
log.Debugf("%#v", state)
|
||||
|
||||
c.lastAuthorizationStateType = stateType
|
||||
|
||||
switch stateType {
|
||||
// stage 0: set login
|
||||
case client.TypeAuthorizationStateWaitPhoneNumber:
|
||||
|
|
@ -262,12 +267,12 @@ func (c *Client) interactor() {
|
|||
if c.Session.Login != "" {
|
||||
c.authorizer.PhoneNumber <- c.Session.Login
|
||||
} else {
|
||||
gateway.SendServiceMessage(c.jid, "Please, enter your Telegram login via /login 12345", c.xmpp)
|
||||
c.wizardStageOrPrompt("login", "Please, enter your Telegram login via /login 12345, or use the Login Wizard via Ad-Hoc commands")
|
||||
}
|
||||
// stage 1: wait for auth code
|
||||
case client.TypeAuthorizationStateWaitCode:
|
||||
log.Warn("Waiting for authorization code...")
|
||||
gateway.SendServiceMessage(c.jid, "Please, enter authorization code via /code 12345", c.xmpp)
|
||||
c.wizardStageOrPrompt("code", "Please, enter authorization code via /code 12345")
|
||||
// stage 1b: wait for registration
|
||||
case client.TypeAuthorizationStateWaitRegistration:
|
||||
log.Warn("Waiting for full name...")
|
||||
|
|
@ -275,7 +280,7 @@ func (c *Client) interactor() {
|
|||
// stage 2: wait for 2fa
|
||||
case client.TypeAuthorizationStateWaitPassword:
|
||||
log.Warn("Waiting for 2FA password...")
|
||||
gateway.SendServiceMessage(c.jid, "Please, enter 2FA passphrase via /password 12345", c.xmpp)
|
||||
c.wizardStageOrPrompt("password", "Please, enter 2FA passphrase via /password 12345")
|
||||
}
|
||||
c.locks.authorizerReadLock.Unlock()
|
||||
}
|
||||
|
|
@ -294,6 +299,7 @@ func (c *Client) forceClose() {
|
|||
func (c *Client) close() {
|
||||
c.locks.authorizerWriteLock.Lock()
|
||||
if c.authorizer != nil && !c.authorizer.isClosed {
|
||||
log.Debug("Closing authorizer")
|
||||
c.authorizer.Close()
|
||||
}
|
||||
c.locks.authorizerWriteLock.Unlock()
|
||||
|
|
@ -308,6 +314,7 @@ func (c *Client) close() {
|
|||
}
|
||||
|
||||
func (c *Client) cancelAuth() {
|
||||
c.StopLoginWizard()
|
||||
c.close()
|
||||
c.Session.Login = ""
|
||||
}
|
||||
|
|
|
|||
82
telegram/loginwizard.go
Normal file
82
telegram/loginwizard.go
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
package telegram
|
||||
|
||||
import (
|
||||
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/zelenin/go-tdlib/client"
|
||||
)
|
||||
|
||||
// StartLoginWizard initiates a loginWizard object
|
||||
func (c *Client) StartLoginWizard(inCommand bool) {
|
||||
if c.loginWizard == nil {
|
||||
c.loginWizard = &loginWizardMetadata{
|
||||
nextStage: make(chan string, 1),
|
||||
commandSent: inCommand,
|
||||
}
|
||||
} else {
|
||||
c.loginWizard.commandSent = inCommand
|
||||
}
|
||||
}
|
||||
|
||||
// StopLoginWizard safely destroys the loginWizard object
|
||||
func (c *Client) StopLoginWizard() {
|
||||
c.locks.loginWizardReadLock.Lock()
|
||||
c.locks.loginWizardWriteLock.Lock()
|
||||
if c.loginWizard != nil {
|
||||
close(c.loginWizard.nextStage)
|
||||
c.loginWizard = nil
|
||||
}
|
||||
c.locks.loginWizardReadLock.Unlock()
|
||||
c.locks.loginWizardWriteLock.Unlock()
|
||||
}
|
||||
|
||||
// GetLoginWizardNextStage waits for the next stage from the channel
|
||||
func (c *Client) GetLoginWizardNextStage() string {
|
||||
c.locks.loginWizardReadLock.Lock()
|
||||
defer c.locks.loginWizardReadLock.Unlock()
|
||||
|
||||
if c.loginWizard != nil {
|
||||
if c.loginWizard.commandSent {
|
||||
log.Debugf("waiting for nextStage...")
|
||||
nextStage := <-c.loginWizard.nextStage
|
||||
c.loginWizard.commandSent = false
|
||||
c.loginWizard.chanBusy = false
|
||||
log.Debugf("yielded stage %v", nextStage)
|
||||
return nextStage
|
||||
} else {
|
||||
if c.lastAuthorizationStateType == client.TypeAuthorizationStateWaitPhoneNumber ||
|
||||
c.lastAuthorizationStateType == client.TypeAuthorizationStateClosing ||
|
||||
c.Session.Login == "" {
|
||||
return "login"
|
||||
}
|
||||
switch c.lastAuthorizationStateType {
|
||||
case client.TypeAuthorizationStateWaitCode:
|
||||
return "code"
|
||||
case client.TypeAuthorizationStateWaitPassword:
|
||||
return "password"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *Client) wizardStageOrPrompt(stage, message string) {
|
||||
c.locks.loginWizardWriteLock.Lock()
|
||||
if c.loginWizard == nil {
|
||||
c.locks.loginWizardWriteLock.Unlock()
|
||||
if message != "" {
|
||||
gateway.SendServiceMessage(c.jid, message, c.xmpp)
|
||||
}
|
||||
} else {
|
||||
if !c.loginWizard.chanBusy {
|
||||
log.Debugf("writing wizard stage %v", stage)
|
||||
c.loginWizard.nextStage <- stage
|
||||
} else {
|
||||
log.Warn("Skipping stage %v, wizard cannot keep up", stage)
|
||||
}
|
||||
c.loginWizard.chanBusy = true
|
||||
c.locks.loginWizardWriteLock.Unlock()
|
||||
}
|
||||
}
|
||||
|
|
@ -679,25 +679,41 @@ func handleGetDiscoItems(s xmpp.Sender, iq *stanza.IQ, di *stanza.DiscoItems) {
|
|||
|
||||
log.Debugf("discoItems: %#v", di)
|
||||
|
||||
_, ok := toToID(iq.To)
|
||||
_, toOk := toToID(iq.To)
|
||||
if di.Node == gateway.NSCommand {
|
||||
answer.Payload = di
|
||||
|
||||
chatType, chatTypeErr := getTelegramChatType(iq.From, iq.To)
|
||||
|
||||
var cmdType telegram.CommandType
|
||||
if ok {
|
||||
if toOk {
|
||||
cmdType = telegram.CommandTypeChat
|
||||
} else {
|
||||
cmdType = telegram.CommandTypeTransport
|
||||
}
|
||||
|
||||
var isOnline bool
|
||||
bare, _, ok := gateway.SplitJID(iq.From)
|
||||
if ok {
|
||||
session, ok := sessions[bare]
|
||||
if ok {
|
||||
isOnline = session.Online()
|
||||
}
|
||||
}
|
||||
|
||||
if !(toOk || isOnline) {
|
||||
di.AddItem(iq.To, "loginwizard", "Login Wizard")
|
||||
}
|
||||
|
||||
commands := telegram.GetCommands(cmdType)
|
||||
for _, name := range telegram.SortedCommandKeys(commands) {
|
||||
command := commands[name]
|
||||
if chatTypeErr == nil && !telegram.IsCommandForChatType(command, chatType) {
|
||||
continue
|
||||
}
|
||||
if !isOnline && command.LoginOnly {
|
||||
continue
|
||||
}
|
||||
di.AddItem(iq.To, name, telegram.CommandToHelpString(name, command))
|
||||
}
|
||||
} else {
|
||||
|
|
@ -851,7 +867,13 @@ func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command
|
|||
return
|
||||
}
|
||||
|
||||
defer gateway.ResumableSend(component, answer)
|
||||
cancelSend := false
|
||||
|
||||
defer func() {
|
||||
if !cancelSend {
|
||||
gateway.ResumableSend(component, answer)
|
||||
}
|
||||
}()
|
||||
|
||||
log.Debugf("command: %#v", command)
|
||||
|
||||
|
|
@ -938,12 +960,20 @@ func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command
|
|||
}
|
||||
|
||||
answer.Payload = &stanza.Command{
|
||||
SessionId: command.Node,
|
||||
Node: command.Node,
|
||||
Status: stanza.CommandStatusCompleted,
|
||||
SessionId: command.Node,
|
||||
Node: command.Node,
|
||||
Status: stanza.CommandStatusCompleted,
|
||||
CommandElements: elements,
|
||||
}
|
||||
}
|
||||
} else if command.Node == "loginwizard" {
|
||||
var session *telegram.Client
|
||||
answer.Payload, cancelSend, session = loginWizardPayload(bare, form, resource)
|
||||
|
||||
log.Debugf("immediate loginwizard payload: %#v", answer.Payload)
|
||||
if cancelSend {
|
||||
go sendLoginWizardResponse(component, answer, session)
|
||||
}
|
||||
} else {
|
||||
// just for the case the client messed the order somehow
|
||||
sort.Slice(form.Fields, func(i int, j int) bool {
|
||||
|
|
@ -1072,10 +1102,24 @@ func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command
|
|||
CommandElements: []stanza.CommandElement{&form},
|
||||
}
|
||||
log.Debugf("form: %#v", form)
|
||||
} else if command.Node == "loginwizard" {
|
||||
var session *telegram.Client
|
||||
answer.Payload, cancelSend, session = loginWizardPayload(bare, nil, resource)
|
||||
|
||||
log.Debugf("immediate loginwizard payload: %#v", answer.Payload)
|
||||
if cancelSend {
|
||||
go sendLoginWizardResponse(component, answer, session)
|
||||
}
|
||||
} else {
|
||||
cmdString = "/" + command.Node
|
||||
}
|
||||
} else if command.Action == stanza.CommandActionCancel {
|
||||
if command.Node == "loginwizard" {
|
||||
session, ok := sessions[bare]
|
||||
if ok {
|
||||
session.ProcessTransportCommand("/cancelauth", resource)
|
||||
}
|
||||
}
|
||||
answer.Payload = &stanza.Command{
|
||||
SessionId: command.Node,
|
||||
Node: command.Node,
|
||||
|
|
@ -1119,7 +1163,7 @@ func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command
|
|||
|
||||
}
|
||||
|
||||
log.Debugf("command response: %#v", answer.Payload)
|
||||
log.Debugf("command response: %#v %v", answer.Payload, cancelSend)
|
||||
}
|
||||
|
||||
func iqAnswerSetError(answer *stanza.IQ, payload *extensions.QueryRegister, code int) {
|
||||
|
|
|
|||
110
xmpp/loginwizard.go
Normal file
110
xmpp/loginwizard.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
package xmpp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"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 setCommandPayloadError(payload *stanza.Command, err string) {
|
||||
note := stanza.Note{
|
||||
Text: err,
|
||||
Type: stanza.CommandNoteTypeErr,
|
||||
}
|
||||
payload.Status = stanza.CommandStatusCompleted
|
||||
payload.CommandElements = append(payload.CommandElements, ¬e)
|
||||
}
|
||||
|
||||
func loginWizardPayload(bare string, requestForm *stanza.Form, resource string) (payload *stanza.Command, cancelSend bool, returnSession *telegram.Client) {
|
||||
payload = &stanza.Command{
|
||||
SessionId: "loginwizard",
|
||||
Node: "loginwizard",
|
||||
}
|
||||
|
||||
session, ok := sessions[bare]
|
||||
if ok {
|
||||
returnSession = session
|
||||
|
||||
if requestForm == nil {
|
||||
session.StartLoginWizard(false)
|
||||
cancelSend = true
|
||||
} 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
|
||||
}
|
||||
switch field.Var {
|
||||
case "login", "code", "password":
|
||||
default:
|
||||
setCommandPayloadError(payload, "Unknown field")
|
||||
return
|
||||
}
|
||||
|
||||
session.StartLoginWizard(true)
|
||||
response, success := session.ProcessTransportCommand(fmt.Sprintf("/%v %v", field.Var, field.ValuesList[0]), 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 := "login"
|
||||
if session != nil {
|
||||
nextStage = session.GetLoginWizardNextStage()
|
||||
}
|
||||
log.Debugf("nextStage: %v", nextStage)
|
||||
|
||||
if nextStage == "cancel" {
|
||||
setCommandPayloadError(payload, "Cancelled")
|
||||
session.StopLoginWizard()
|
||||
} else if nextStage == "success" {
|
||||
payload.Status = stanza.CommandStatusCompleted
|
||||
session.StopLoginWizard()
|
||||
} else {
|
||||
required := ""
|
||||
form := stanza.Form{
|
||||
Type: stanza.FormTypeForm,
|
||||
Title: "Login Wizard",
|
||||
Fields: []*stanza.Field{
|
||||
&stanza.Field{
|
||||
Var: nextStage,
|
||||
Label: nextStage,
|
||||
Required: &required,
|
||||
},
|
||||
},
|
||||
}
|
||||
payload.Status = stanza.CommandStatusExecuting
|
||||
payload.CommandElements = append(payload.CommandElements, &form)
|
||||
}
|
||||
|
||||
answer.Payload = payload
|
||||
|
||||
gateway.ResumableSend(component, answer)
|
||||
}
|
||||
Loading…
Reference in a new issue