forked from MirrorHub/mautrix-whatsapp
Implement logout and provisioning API login
This commit is contained in:
parent
7aa838dce6
commit
ded2fb9799
7 changed files with 226 additions and 336 deletions
|
@ -188,7 +188,7 @@ func (prov *ProvisioningAPI) BridgeStatePing(w http.ResponseWriter, r *http.Requ
|
|||
var global BridgeState
|
||||
global.StateEvent = StateRunning
|
||||
var remote BridgeState
|
||||
if user.Client != nil && user.Client.IsConnected() {
|
||||
if user.IsConnected() {
|
||||
if user.Client.IsLoggedIn {
|
||||
remote.StateEvent = StateConnected
|
||||
} else if user.Session != nil {
|
||||
|
|
142
commands.go
142
commands.go
|
@ -22,15 +22,14 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/skip2/go-qrcode"
|
||||
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
"go.mau.fi/whatsmeow/types/events"
|
||||
|
||||
"maunium.net/go/maulogger/v2"
|
||||
|
||||
"go.mau.fi/whatsmeow"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/appservice"
|
||||
"maunium.net/go/mautrix/event"
|
||||
|
@ -377,95 +376,63 @@ func (handler *CommandHandler) CommandSetPowerLevel(ce *CommandEvent) {
|
|||
}
|
||||
}
|
||||
|
||||
const cmdLoginHelp = `login - Authenticate this Bridge as WhatsApp Web Client`
|
||||
const cmdLoginHelp = `login - Link the bridge to your WhatsApp account as a web client`
|
||||
|
||||
// CommandLogin handles login command
|
||||
func (handler *CommandHandler) CommandLogin(ce *CommandEvent) {
|
||||
if ce.User.Session != nil {
|
||||
ce.Reply("You're already logged in")
|
||||
return
|
||||
}
|
||||
qrChan := make(chan *events.QR, 1)
|
||||
loginChan := make(chan *events.PairSuccess, 1)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go ce.User.loginQrChannel(ctx, ce, qrChan, cancel)
|
||||
|
||||
ce.User.qrListener = qrChan
|
||||
ce.User.loginListener = loginChan
|
||||
if !ce.User.Connect(true) {
|
||||
ce.User.log.Debugln("Connect() returned false, assuming error was logged elsewhere and canceling login.")
|
||||
if ce.User.IsConnected() {
|
||||
ce.Reply("You're already logged in")
|
||||
} else {
|
||||
ce.Reply("You're already logged in. Perhaps you wanted to `reconnect`?")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case success := <-loginChan:
|
||||
ce.Reply("Successfully logged in as +%s (device #%d)", success.ID.User, success.ID.Device)
|
||||
cancel()
|
||||
case <-ctx.Done():
|
||||
ce.Reply("Login timed out")
|
||||
}
|
||||
}
|
||||
|
||||
func (user *User) loginQrChannel(ctx context.Context, ce *CommandEvent, qrChan <-chan *events.QR, cancel func()) {
|
||||
var qrEvt *events.QR
|
||||
select {
|
||||
case qrEvt = <-qrChan:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
|
||||
bot := user.bridge.AS.BotClient()
|
||||
|
||||
code := qrEvt.Codes[0]
|
||||
qrEvt.Codes = qrEvt.Codes[1:]
|
||||
url, ok := user.uploadQR(ce, code)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
sendResp, err := bot.SendImage(ce.RoomID, code, url)
|
||||
qrChan, err := ce.User.Login(context.Background())
|
||||
if err != nil {
|
||||
user.log.Errorln("Failed to send QR code to user:", err)
|
||||
ce.User.log.Errorf("Failed to log in:", err)
|
||||
ce.Reply("Failed to log in: %v", err)
|
||||
return
|
||||
}
|
||||
qrEventID := sendResp.EventID
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-time.After(qrEvt.Timeout):
|
||||
if len(qrEvt.Codes) == 0 {
|
||||
_, _ = bot.RedactEvent(ce.RoomID, qrEventID)
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
code, qrEvt.Codes = qrEvt.Codes[0], qrEvt.Codes[1:]
|
||||
|
||||
url, ok = user.uploadQR(ce, code)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
_, err = bot.SendMessageEvent(ce.RoomID, event.EventMessage, &event.MessageEventContent{
|
||||
MsgType: event.MsgImage,
|
||||
Body: code,
|
||||
URL: url.CUString(),
|
||||
NewContent: &event.MessageEventContent{
|
||||
MsgType: event.MsgImage,
|
||||
Body: code,
|
||||
URL: url.CUString(),
|
||||
},
|
||||
RelatesTo: &event.RelatesTo{
|
||||
Type: event.RelReplace,
|
||||
EventID: qrEventID,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
user.log.Errorln("Failed to send edited QR code to user:", err)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
_, _ = bot.RedactEvent(ce.RoomID, qrEventID)
|
||||
return
|
||||
var qrEventID id.EventID
|
||||
for item := range qrChan {
|
||||
switch item {
|
||||
case whatsmeow.QRChannelSuccess:
|
||||
jid := ce.User.Client.Store.ID
|
||||
ce.Reply("Successfully logged in as +%s (device #%d)", jid.User, jid.Device)
|
||||
case whatsmeow.QRChannelTimeout:
|
||||
ce.Reply("QR code timed out. Please restart the login.")
|
||||
case whatsmeow.QRChannelErrUnexpectedEvent:
|
||||
ce.Reply("Failed to log in: unexpected connection event from server")
|
||||
default:
|
||||
qrEventID = ce.User.sendQR(ce, string(item), qrEventID)
|
||||
}
|
||||
}
|
||||
_, _ = ce.Bot.RedactEvent(ce.RoomID, qrEventID)
|
||||
}
|
||||
|
||||
func (user *User) sendQR(ce *CommandEvent, code string, prevEvent id.EventID) id.EventID {
|
||||
url, ok := user.uploadQR(ce, code)
|
||||
if !ok {
|
||||
return prevEvent
|
||||
}
|
||||
content := event.MessageEventContent{
|
||||
MsgType: event.MsgImage,
|
||||
Body: code,
|
||||
URL: url.CUString(),
|
||||
}
|
||||
if len(prevEvent) != 0 {
|
||||
content.SetEdit(prevEvent)
|
||||
}
|
||||
resp, err := ce.Bot.SendMessageEvent(ce.RoomID, event.EventMessage, &content)
|
||||
if err != nil {
|
||||
user.log.Errorln("Failed to send edited QR code to user:", err)
|
||||
} else if len(prevEvent) == 0 {
|
||||
prevEvent = resp.EventID
|
||||
}
|
||||
return prevEvent
|
||||
}
|
||||
|
||||
func (user *User) uploadQR(ce *CommandEvent, code string) (id.ContentURI, bool) {
|
||||
|
@ -487,7 +454,7 @@ func (user *User) uploadQR(ce *CommandEvent, code string) (id.ContentURI, bool)
|
|||
return resp.ContentURI, true
|
||||
}
|
||||
|
||||
const cmdLogoutHelp = `logout - Logout from WhatsApp`
|
||||
const cmdLogoutHelp = `logout - Unlink the bridge from your WhatsApp account`
|
||||
|
||||
// CommandLogout handles !logout command
|
||||
func (handler *CommandHandler) CommandLogout(ce *CommandEvent) {
|
||||
|
@ -505,13 +472,12 @@ func (handler *CommandHandler) CommandLogout(ce *CommandEvent) {
|
|||
ce.User.log.Warnln("Failed to logout-matrix while logging out of WhatsApp:", err)
|
||||
}
|
||||
}
|
||||
// TODO reimplement
|
||||
//err := ce.User.Client.Logout()
|
||||
//if err != nil {
|
||||
// ce.User.log.Warnln("Error while logging out:", err)
|
||||
// ce.Reply("Unknown error while logging out: %v", err)
|
||||
// return
|
||||
//}
|
||||
err := ce.User.Client.Logout()
|
||||
if err != nil {
|
||||
ce.User.log.Warnln("Error while logging out:", err)
|
||||
ce.Reply("Unknown error while logging out: %v", err)
|
||||
return
|
||||
}
|
||||
ce.User.removeFromJIDMap(StateLoggedOut)
|
||||
ce.User.DeleteConnection()
|
||||
ce.User.DeleteSession()
|
||||
|
|
16
go.mod
16
go.mod
|
@ -8,13 +8,13 @@ require (
|
|||
github.com/mattn/go-sqlite3 v1.14.9
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
go.mau.fi/whatsmeow v0.0.0-20211026140006-b484ee326162
|
||||
go.mau.fi/whatsmeow v0.0.0-20211027125031-660696c7c724
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
maunium.net/go/mauflag v1.0.0
|
||||
maunium.net/go/maulogger/v2 v2.3.0
|
||||
maunium.net/go/mautrix v0.9.30
|
||||
maunium.net/go/maulogger/v2 v2.3.1
|
||||
maunium.net/go/mautrix v0.9.31
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -29,12 +29,12 @@ require (
|
|||
github.com/prometheus/common v0.26.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/tidwall/gjson v1.6.8 // indirect
|
||||
github.com/tidwall/match v1.0.3 // indirect
|
||||
github.com/tidwall/pretty v1.0.2 // indirect
|
||||
github.com/tidwall/sjson v1.1.5 // indirect
|
||||
github.com/tidwall/gjson v1.10.2 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tidwall/sjson v1.2.3 // indirect
|
||||
go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
|
||||
)
|
||||
|
|
43
go.sum
43
go.sum
|
@ -77,10 +77,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
|||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg=
|
||||
github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
|
@ -129,26 +127,25 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/gjson v1.6.8 h1:CTmXMClGYPAmln7652e69B7OLXfTi5ABcPPwjIWUv7w=
|
||||
github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
|
||||
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
|
||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
|
||||
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/sjson v1.1.5 h1:wsUceI/XDyZk3J1FUvuuYlK62zJv2HO2Pzb8A5EWdUE=
|
||||
github.com/tidwall/sjson v1.1.5/go.mod h1:VuJzsZnTowhSxWdOgsAnb886i4AjEyTkk7tNtsL7EYE=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo=
|
||||
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.3 h1:5+deguEhHSEjmuICXZ21uSSsXotWMA0orU783+Z7Cp8=
|
||||
github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs=
|
||||
go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2 h1:xpQTMgJGGaF+c8jV/LA/FVXAPJxZbSAGeflOc+Ly6uQ=
|
||||
go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2/go.mod h1:3XlVlwOfp8f9Wri+C1D4ORqgUsN4ZvunJOoPjQMBhos=
|
||||
go.mau.fi/whatsmeow v0.0.0-20211026140006-b484ee326162 h1:nwQ9gDQsvAmhW6B2a97RV0bkO9PEb7C7UZiMEYADRtw=
|
||||
go.mau.fi/whatsmeow v0.0.0-20211026140006-b484ee326162/go.mod h1:ODEmmqeUn9eBDQHFc1S902YA3YFLtmaBujYRRFl53jI=
|
||||
go.mau.fi/whatsmeow v0.0.0-20211027125031-660696c7c724 h1:vk1AkBxc0tVEmPa5mUrzMNwA5wMe/yKrILr32xgW4KA=
|
||||
go.mau.fi/whatsmeow v0.0.0-20211027125031-660696c7c724/go.mod h1:ODEmmqeUn9eBDQHFc1S902YA3YFLtmaBujYRRFl53jI=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
|
||||
|
@ -160,9 +157,9 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI=
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -175,17 +172,16 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
|
@ -221,8 +217,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie
|
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
||||
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
||||
maunium.net/go/maulogger/v2 v2.2.4/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
||||
maunium.net/go/maulogger/v2 v2.3.0 h1:TMCcO65fLk6+pJXo7sl38tzjzW0KBFgc6JWJMBJp4GE=
|
||||
maunium.net/go/maulogger/v2 v2.3.0/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
||||
maunium.net/go/mautrix v0.9.30 h1:iOJ9Cl576jxCL1x8J3bKQx29nc5hoewZlVyPmNWdzF8=
|
||||
maunium.net/go/mautrix v0.9.30/go.mod h1:7IzKfWvpQtN+W2Lzxc0rLvIxFM3ryKX6Ys3S/ZoWbg8=
|
||||
maunium.net/go/maulogger/v2 v2.3.1 h1:fwBYJne0pHvJrrIPHK+TAPfyxxbBEz46oVGez2x0ODE=
|
||||
maunium.net/go/maulogger/v2 v2.3.1/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
||||
maunium.net/go/mautrix v0.9.31 h1:n7UF5tqq2zCyfdNsv++RyQ2anjjrFVOmOA2VkZCSgZc=
|
||||
maunium.net/go/mautrix v0.9.31/go.mod h1:3U7pOAx4bxdIVJuunLDAToI+M7YwxcGMm74zBmX5aY0=
|
||||
|
|
4
main.go
4
main.go
|
@ -365,7 +365,7 @@ func (bridge *Bridge) LoadRelaybot() {
|
|||
}
|
||||
bridge.Relaybot.ManagementRoom = bridge.Config.Bridge.Relaybot.ManagementRoom
|
||||
bridge.Relaybot.IsRelaybot = true
|
||||
bridge.Relaybot.Connect(false)
|
||||
bridge.Relaybot.Connect()
|
||||
}
|
||||
|
||||
func (bridge *Bridge) UpdateBotProfile() {
|
||||
|
@ -403,7 +403,7 @@ func (bridge *Bridge) StartUsers() {
|
|||
if !user.JID.IsEmpty() {
|
||||
foundAnySessions = true
|
||||
}
|
||||
go user.Connect(false)
|
||||
go user.Connect()
|
||||
}
|
||||
if !foundAnySessions {
|
||||
bridge.sendGlobalBridgeState(BridgeState{StateEvent: StateUnconfigured}.fill(nil))
|
||||
|
|
276
provisioning.go
276
provisioning.go
|
@ -21,6 +21,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
@ -28,6 +29,8 @@ import (
|
|||
|
||||
"github.com/gorilla/websocket"
|
||||
|
||||
"go.mau.fi/whatsmeow"
|
||||
|
||||
log "maunium.net/go/maulogger/v2"
|
||||
|
||||
"maunium.net/go/mautrix/id"
|
||||
|
@ -47,11 +50,13 @@ func (prov *ProvisioningAPI) Init() {
|
|||
r.HandleFunc("/login", prov.Login).Methods(http.MethodGet)
|
||||
r.HandleFunc("/logout", prov.Logout).Methods(http.MethodPost)
|
||||
r.HandleFunc("/delete_session", prov.DeleteSession).Methods(http.MethodPost)
|
||||
r.HandleFunc("/delete_connection", prov.DeleteConnection).Methods(http.MethodPost)
|
||||
r.HandleFunc("/disconnect", prov.Disconnect).Methods(http.MethodPost)
|
||||
r.HandleFunc("/reconnect", prov.Reconnect).Methods(http.MethodPost)
|
||||
prov.bridge.AS.Router.HandleFunc("/_matrix/app/com.beeper.asmux/ping", prov.BridgeStatePing).Methods(http.MethodPost)
|
||||
prov.bridge.AS.Router.HandleFunc("/_matrix/app/com.beeper.bridge_state", prov.BridgeStatePing).Methods(http.MethodPost)
|
||||
|
||||
// Deprecated, just use /disconnect
|
||||
r.HandleFunc("/delete_connection", prov.Disconnect).Methods(http.MethodPost)
|
||||
}
|
||||
|
||||
type responseWrap struct {
|
||||
|
@ -131,19 +136,6 @@ func (prov *ProvisioningAPI) DeleteSession(w http.ResponseWriter, r *http.Reques
|
|||
jsonResponse(w, http.StatusOK, Response{true, "Session information purged"})
|
||||
}
|
||||
|
||||
func (prov *ProvisioningAPI) DeleteConnection(w http.ResponseWriter, r *http.Request) {
|
||||
user := r.Context().Value("user").(*User)
|
||||
if user.Client == nil {
|
||||
jsonResponse(w, http.StatusNotFound, Error{
|
||||
Error: "You don't have a WhatsApp connection.",
|
||||
ErrCode: "not connected",
|
||||
})
|
||||
return
|
||||
}
|
||||
user.DeleteConnection()
|
||||
jsonResponse(w, http.StatusOK, Response{true, "Disconnected from WhatsApp and connection deleted"})
|
||||
}
|
||||
|
||||
func (prov *ProvisioningAPI) Disconnect(w http.ResponseWriter, r *http.Request) {
|
||||
user := r.Context().Value("user").(*User)
|
||||
if user.Client == nil {
|
||||
|
@ -166,75 +158,14 @@ func (prov *ProvisioningAPI) Reconnect(w http.ResponseWriter, r *http.Request) {
|
|||
ErrCode: "no session",
|
||||
})
|
||||
} else {
|
||||
user.Connect(false)
|
||||
jsonResponse(w, http.StatusOK, Response{true, "Created connection to WhatsApp."})
|
||||
user.Connect()
|
||||
jsonResponse(w, http.StatusAccepted, Response{true, "Created connection to WhatsApp."})
|
||||
}
|
||||
return
|
||||
} else {
|
||||
user.DeleteConnection()
|
||||
user.Connect()
|
||||
jsonResponse(w, http.StatusAccepted, Response{true, "Restarted connection to WhatsApp"})
|
||||
}
|
||||
|
||||
// TODO reimplement
|
||||
//user.log.Debugln("Received /reconnect request, disconnecting")
|
||||
//wasConnected := true
|
||||
//err := user.Conn.Disconnect()
|
||||
//if err == whatsapp.ErrNotConnected {
|
||||
// wasConnected = false
|
||||
//} else if err != nil {
|
||||
// user.log.Warnln("Error while disconnecting:", err)
|
||||
//}
|
||||
//
|
||||
//user.log.Debugln("Restoring session for /reconnect")
|
||||
//err = user.Conn.Restore(true, r.Context())
|
||||
//user.log.Debugfln("Restore session for /reconnect responded with %v", err)
|
||||
//if err == whatsapp.ErrInvalidSession {
|
||||
// if user.Session != nil {
|
||||
// user.log.Debugln("Got invalid session error when reconnecting, but user has session. Retrying using RestoreWithSession()...")
|
||||
// user.Conn.SetSession(*user.Session)
|
||||
// err = user.Conn.Restore(true, r.Context())
|
||||
// } else {
|
||||
// jsonResponse(w, http.StatusForbidden, Error{
|
||||
// Error: "You're not logged in",
|
||||
// ErrCode: "not logged in",
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
//}
|
||||
//if err == whatsapp.ErrLoginInProgress {
|
||||
// jsonResponse(w, http.StatusConflict, Error{
|
||||
// Error: "A login or reconnection is already in progress.",
|
||||
// ErrCode: "login in progress",
|
||||
// })
|
||||
// return
|
||||
//} else if err == whatsapp.ErrAlreadyLoggedIn {
|
||||
// jsonResponse(w, http.StatusConflict, Error{
|
||||
// Error: "You were already connected.",
|
||||
// ErrCode: err.Error(),
|
||||
// })
|
||||
// return
|
||||
//}
|
||||
//if err != nil {
|
||||
// user.log.Warnln("Error while reconnecting:", err)
|
||||
// jsonResponse(w, http.StatusInternalServerError, Error{
|
||||
// Error: fmt.Sprintf("Unknown error while reconnecting: %v", err),
|
||||
// ErrCode: err.Error(),
|
||||
// })
|
||||
// user.log.Debugln("Disconnecting due to failed session restore in reconnect command...")
|
||||
// err = user.Conn.Disconnect()
|
||||
// if err != nil {
|
||||
// user.log.Errorln("Failed to disconnect after failed session restore in reconnect command:", err)
|
||||
// }
|
||||
// return
|
||||
//}
|
||||
//user.ConnectionErrors = 0
|
||||
//user.PostLogin()
|
||||
//
|
||||
//var msg string
|
||||
//if wasConnected {
|
||||
// msg = "Reconnected successfully."
|
||||
//} else {
|
||||
// msg = "Connected successfully."
|
||||
//}
|
||||
//
|
||||
//jsonResponse(w, http.StatusOK, Response{true, msg})
|
||||
}
|
||||
|
||||
func (prov *ProvisioningAPI) Ping(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -289,18 +220,17 @@ func (prov *ProvisioningAPI) Logout(w http.ResponseWriter, r *http.Request) {
|
|||
})
|
||||
}
|
||||
} else {
|
||||
// TODO reimplement
|
||||
//err := user.Client.Logout()
|
||||
//if err != nil {
|
||||
// user.log.Warnln("Error while logging out:", err)
|
||||
// if !force {
|
||||
// jsonResponse(w, http.StatusInternalServerError, Error{
|
||||
// Error: fmt.Sprintf("Unknown error while logging out: %v", err),
|
||||
// ErrCode: err.Error(),
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
//}
|
||||
err := user.Client.Logout()
|
||||
if err != nil {
|
||||
user.log.Warnln("Error while logging out:", err)
|
||||
if !force {
|
||||
jsonResponse(w, http.StatusInternalServerError, Error{
|
||||
Error: fmt.Sprintf("Unknown error while logging out: %v", err),
|
||||
ErrCode: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
user.DeleteConnection()
|
||||
}
|
||||
|
||||
|
@ -318,88 +248,82 @@ var upgrader = websocket.Upgrader{
|
|||
}
|
||||
|
||||
func (prov *ProvisioningAPI) Login(w http.ResponseWriter, r *http.Request) {
|
||||
userID := r.URL.Query().Get("user_id")
|
||||
user := prov.bridge.GetUserByMXID(id.UserID(userID))
|
||||
|
||||
// TODO reimplement
|
||||
//userID := r.URL.Query().Get("user_id")
|
||||
//user := prov.bridge.GetUserByMXID(id.UserID(userID))
|
||||
//
|
||||
//c, err := upgrader.Upgrade(w, r, nil)
|
||||
//if err != nil {
|
||||
// prov.log.Errorln("Failed to upgrade connection to websocket:", err)
|
||||
// return
|
||||
//}
|
||||
//defer c.Close()
|
||||
//if !user.Connect(true) {
|
||||
// user.log.Debugln("Connect() returned false, assuming error was logged elsewhere and canceling login.")
|
||||
// _ = c.WriteJSON(Error{
|
||||
// Error: "Failed to connect to WhatsApp",
|
||||
// ErrCode: "connection error",
|
||||
// })
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//qrChan := make(chan string, 3)
|
||||
//go func() {
|
||||
// for code := range qrChan {
|
||||
// if code == "stop" {
|
||||
// return
|
||||
// }
|
||||
// _ = c.WriteJSON(map[string]interface{}{
|
||||
// "code": code,
|
||||
// })
|
||||
// }
|
||||
//}()
|
||||
//
|
||||
//go func() {
|
||||
// // Read everything so SetCloseHandler() works
|
||||
// for {
|
||||
// _, _, err = c.ReadMessage()
|
||||
// if err != nil {
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
//}()
|
||||
//ctx, cancel := context.WithCancel(context.Background())
|
||||
//c.SetCloseHandler(func(code int, text string) error {
|
||||
// user.log.Debugfln("Login websocket closed (%d), cancelling login", code)
|
||||
// cancel()
|
||||
// return nil
|
||||
//})
|
||||
//
|
||||
//user.log.Debugln("Starting login via provisioning API")
|
||||
//session, jid, err := user.Conn.Login(qrChan, ctx)
|
||||
//qrChan <- "stop"
|
||||
//if err != nil {
|
||||
// var msg string
|
||||
// if errors.Is(err, whatsapp.ErrAlreadyLoggedIn) {
|
||||
// msg = "You're already logged in"
|
||||
// } else if errors.Is(err, whatsapp.ErrLoginInProgress) {
|
||||
// msg = "You have a login in progress already."
|
||||
// } else if errors.Is(err, whatsapp.ErrLoginTimedOut) {
|
||||
// msg = "QR code scan timed out. Please try again."
|
||||
// } else if errors.Is(err, whatsapp.ErrInvalidWebsocket) {
|
||||
// msg = "WhatsApp connection error. Please try again."
|
||||
// // TODO might need to make sure it reconnects?
|
||||
// } else if errors.Is(err, whatsapp.ErrMultiDeviceNotSupported) {
|
||||
// msg = "WhatsApp multi-device is not currently supported. Please disable it and try again."
|
||||
// } else {
|
||||
// msg = fmt.Sprintf("Unknown error while logging in: %v", err)
|
||||
// }
|
||||
// user.log.Warnln("Failed to log in:", err)
|
||||
// _ = c.WriteJSON(Error{
|
||||
// Error: msg,
|
||||
// ErrCode: err.Error(),
|
||||
// })
|
||||
// return
|
||||
//}
|
||||
//user.log.Debugln("Successful login as", jid, "via provisioning API")
|
||||
//user.ConnectionErrors = 0
|
||||
//user.JID = strings.Replace(jid, whatsapp.OldUserSuffix, whatsapp.NewUserSuffix, 1)
|
||||
//user.addToJIDMap()
|
||||
//user.SetSession(&session)
|
||||
//_ = c.WriteJSON(map[string]interface{}{
|
||||
// "success": true,
|
||||
// "jid": user.JID,
|
||||
//})
|
||||
//user.PostLogin()
|
||||
c, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
prov.log.Errorln("Failed to upgrade connection to websocket:", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
err := c.Close()
|
||||
if err != nil {
|
||||
user.log.Debugln("Error closing websocket:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
// Read everything so SetCloseHandler() works
|
||||
for {
|
||||
_, _, err = c.ReadMessage()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
c.SetCloseHandler(func(code int, text string) error {
|
||||
user.log.Debugfln("Login websocket closed (%d), cancelling login", code)
|
||||
cancel()
|
||||
return nil
|
||||
})
|
||||
|
||||
qrChan, err := user.Login(ctx)
|
||||
if err != nil {
|
||||
user.log.Errorf("Failed to log in from provisioning API:", err)
|
||||
if errors.Is(err, ErrAlreadyLoggedIn) {
|
||||
go user.Connect()
|
||||
_ = c.WriteJSON(Error{
|
||||
Error: "You're already logged into WhatsApp",
|
||||
ErrCode: "already logged in",
|
||||
})
|
||||
} else {
|
||||
_ = c.WriteJSON(Error{
|
||||
Error: "Failed to connect to WhatsApp",
|
||||
ErrCode: "connection error",
|
||||
})
|
||||
}
|
||||
}
|
||||
user.log.Debugln("Started login via provisioning API")
|
||||
|
||||
for {
|
||||
select {
|
||||
case evt := <-qrChan:
|
||||
switch evt {
|
||||
case whatsmeow.QRChannelSuccess:
|
||||
jid := user.Client.Store.ID
|
||||
user.log.Debugln("Successful login as", jid, "via provisioning API")
|
||||
_ = c.WriteJSON(map[string]interface{}{
|
||||
"success": true,
|
||||
"jid": jid,
|
||||
"phone": fmt.Sprintf("+%s", jid.User),
|
||||
})
|
||||
case whatsmeow.QRChannelTimeout:
|
||||
user.log.Debugln("Login via provisioning API timed out")
|
||||
_ = c.WriteJSON(Error{
|
||||
Error: "QR code scan timed out. Please try again.",
|
||||
ErrCode: "login timed out",
|
||||
})
|
||||
default:
|
||||
_ = c.WriteJSON(map[string]interface{}{
|
||||
"code": string(evt),
|
||||
})
|
||||
continue
|
||||
}
|
||||
return
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
79
user.go
79
user.go
|
@ -17,6 +17,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -62,9 +63,6 @@ type User struct {
|
|||
mgmtCreateLock sync.Mutex
|
||||
connLock sync.Mutex
|
||||
|
||||
qrListener chan<- *events.QR
|
||||
loginListener chan<- *events.PairSuccess
|
||||
|
||||
historySyncs chan *events.HistorySync
|
||||
|
||||
prevBridgeStatus *BridgeState
|
||||
|
@ -141,7 +139,7 @@ func (bridge *Bridge) loadDBUser(dbUser *database.User, mxid *id.UserID) *User {
|
|||
var err error
|
||||
user.Session, err = bridge.WAContainer.GetDevice(user.JID)
|
||||
if err != nil {
|
||||
user.log.Errorfln("Failed to scan user's whatsapp session: %v", err)
|
||||
user.log.Errorfln("Failed to load user's whatsapp session: %v", err)
|
||||
} else if user.Session == nil {
|
||||
user.log.Warnfln("Didn't find session data for %s, treating user as logged out", user.JID)
|
||||
user.JID = types.EmptyJID
|
||||
|
@ -238,25 +236,41 @@ func (w *waLogger) Warnf(msg string, args ...interface{}) { w.l.Warnfln(msg, ar
|
|||
func (w *waLogger) Errorf(msg string, args ...interface{}) { w.l.Errorfln(msg, args...) }
|
||||
func (w *waLogger) Sub(module string) waLog.Logger { return &waLogger{l: w.l.Sub(module)} }
|
||||
|
||||
func (user *User) Connect(evenIfNoSession bool) bool {
|
||||
var ErrAlreadyLoggedIn = errors.New("already logged in")
|
||||
|
||||
func (user *User) Login(ctx context.Context) (<-chan whatsmeow.QRChannelItem, error) {
|
||||
user.connLock.Lock()
|
||||
defer user.connLock.Unlock()
|
||||
if user.Session != nil {
|
||||
return nil, ErrAlreadyLoggedIn
|
||||
} else if user.Client != nil {
|
||||
user.unlockedDeleteConnection()
|
||||
}
|
||||
newSession := user.bridge.WAContainer.NewDevice()
|
||||
newSession.Log = &waLogger{user.log.Sub("Session")}
|
||||
user.Client = whatsmeow.NewClient(newSession, &waLogger{user.log.Sub("Client")})
|
||||
qrChan, err := user.Client.GetQRChannel(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get QR channel: %w", err)
|
||||
}
|
||||
err = user.Client.Connect()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to WhatsApp: %w", err)
|
||||
}
|
||||
return qrChan, nil
|
||||
}
|
||||
|
||||
func (user *User) Connect() bool {
|
||||
user.connLock.Lock()
|
||||
defer user.connLock.Unlock()
|
||||
if user.Client != nil {
|
||||
return user.Client.IsConnected()
|
||||
} else if !evenIfNoSession && user.Session == nil {
|
||||
} else if user.Session == nil {
|
||||
return false
|
||||
}
|
||||
user.log.Debugln("Connecting to WhatsApp")
|
||||
if user.Session != nil {
|
||||
user.sendBridgeState(BridgeState{StateEvent: StateConnecting, Error: WAConnecting})
|
||||
}
|
||||
if user.Session == nil {
|
||||
newSession := user.bridge.WAContainer.NewDevice()
|
||||
newSession.Log = &waLogger{user.log.Sub("Session")}
|
||||
user.Client = whatsmeow.NewClient(newSession, &waLogger{user.log.Sub("Client")})
|
||||
} else {
|
||||
user.Client = whatsmeow.NewClient(user.Session, &waLogger{user.log.Sub("Client")})
|
||||
}
|
||||
user.sendBridgeState(BridgeState{StateEvent: StateConnecting, Error: WAConnecting})
|
||||
user.Client = whatsmeow.NewClient(user.Session, &waLogger{user.log.Sub("Client")})
|
||||
user.Client.AddEventHandler(user.HandleEvent)
|
||||
err := user.Client.Connect()
|
||||
if err != nil {
|
||||
|
@ -266,9 +280,7 @@ func (user *User) Connect(evenIfNoSession bool) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (user *User) DeleteConnection() {
|
||||
user.connLock.Lock()
|
||||
defer user.connLock.Unlock()
|
||||
func (user *User) unlockedDeleteConnection() {
|
||||
if user.Client == nil {
|
||||
return
|
||||
}
|
||||
|
@ -276,6 +288,12 @@ func (user *User) DeleteConnection() {
|
|||
user.Client.RemoveEventHandlers()
|
||||
user.Client = nil
|
||||
user.bridge.Metrics.TrackConnectionState(user.JID, false)
|
||||
}
|
||||
|
||||
func (user *User) DeleteConnection() {
|
||||
user.connLock.Lock()
|
||||
defer user.connLock.Unlock()
|
||||
user.unlockedDeleteConnection()
|
||||
user.sendBridgeState(BridgeState{StateEvent: StateBadCredentials, Error: WANotConnected})
|
||||
}
|
||||
|
||||
|
@ -297,8 +315,12 @@ func (user *User) DeleteSession() {
|
|||
}
|
||||
}
|
||||
|
||||
func (user *User) IsConnected() bool {
|
||||
return user.Client != nil && user.Client.IsConnected()
|
||||
}
|
||||
|
||||
func (user *User) IsLoggedIn() bool {
|
||||
return user.Client != nil && user.Client.IsConnected() && user.Client.IsLoggedIn
|
||||
return user.IsConnected() && user.Client.IsLoggedIn
|
||||
}
|
||||
|
||||
func (user *User) tryAutomaticDoublePuppeting() {
|
||||
|
@ -400,23 +422,6 @@ func (user *User) HandleEvent(event interface{}) {
|
|||
user.addToJIDMap()
|
||||
user.Update()
|
||||
user.Session = user.Client.Store
|
||||
if user.loginListener != nil {
|
||||
select {
|
||||
case user.loginListener <- v:
|
||||
return
|
||||
default:
|
||||
}
|
||||
}
|
||||
user.log.Warnln("Got pair success event, but nothing waiting for it")
|
||||
case *events.QR:
|
||||
if user.qrListener != nil {
|
||||
select {
|
||||
case user.qrListener <- v:
|
||||
return
|
||||
default:
|
||||
}
|
||||
}
|
||||
user.log.Warnln("Got QR code event, but nothing waiting for it")
|
||||
case *events.ConnectFailure, *events.StreamError:
|
||||
go user.sendBridgeState(BridgeState{StateEvent: StateUnknownError})
|
||||
user.bridge.Metrics.TrackConnectionState(user.JID, false)
|
||||
|
|
Loading…
Reference in a new issue