Add timeout for starting google account pairing
This commit is contained in:
parent
847b9a3a90
commit
cf698ed7d6
3 changed files with 45 additions and 10 deletions
11
commands.go
11
commands.go
|
@ -159,10 +159,11 @@ func fnLoginGoogle(ce *WrappedCommandEvent) {
|
|||
}
|
||||
|
||||
const (
|
||||
pairingErrMsgNoDevices = "No devices found. Make sure you've enabled account pairing in the Google Messages app on your phone."
|
||||
pairingErrMsgIncorrectEmoji = "Incorrect emoji chosen on phone, please try again"
|
||||
pairingErrMsgCancelled = "Pairing cancelled on phone"
|
||||
pairingErrMsgTimeout = "Pairing timed out, please try again"
|
||||
pairingErrMsgNoDevices = "No devices found. Make sure you've enabled account pairing in the Google Messages app on your phone."
|
||||
pairingErrPhoneNotResponding = "Phone not responding. Make sure your phone is connected to the internet and that account pairing is enabled in the Google Messages app."
|
||||
pairingErrMsgIncorrectEmoji = "Incorrect emoji chosen on phone, please try again"
|
||||
pairingErrMsgCancelled = "Pairing cancelled on phone"
|
||||
pairingErrMsgTimeout = "Pairing timed out, please try again"
|
||||
)
|
||||
|
||||
func fnLoginGoogleCookies(ce *WrappedCommandEvent) {
|
||||
|
@ -194,6 +195,8 @@ func fnLoginGoogleCookies(ce *WrappedCommandEvent) {
|
|||
if err != nil {
|
||||
if errors.Is(err, libgm.ErrNoDevicesFound) {
|
||||
ce.Reply(pairingErrMsgNoDevices)
|
||||
} else if errors.Is(err, libgm.ErrPairingInitTimeout) {
|
||||
ce.Reply(pairingErrPhoneNotResponding)
|
||||
} else if errors.Is(err, libgm.ErrIncorrectEmoji) {
|
||||
ce.Reply(pairingErrMsgIncorrectEmoji)
|
||||
} else if errors.Is(err, libgm.ErrPairingCancelled) {
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog"
|
||||
"go.mau.fi/util/random"
|
||||
"golang.org/x/crypto/hkdf"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
@ -237,13 +238,16 @@ func (ps *PairingSession) ProcessServerInit(msg *gmproto.GaiaPairingResponseCont
|
|||
}
|
||||
|
||||
var (
|
||||
ErrNoCookies = errors.New("gaia pairing requires cookies")
|
||||
ErrNoDevicesFound = errors.New("no devices found for gaia pairing")
|
||||
ErrIncorrectEmoji = errors.New("user chose incorrect emoji on phone")
|
||||
ErrPairingCancelled = errors.New("user cancelled pairing on phone")
|
||||
ErrPairingTimeout = errors.New("pairing timed out")
|
||||
ErrNoCookies = errors.New("gaia pairing requires cookies")
|
||||
ErrNoDevicesFound = errors.New("no devices found for gaia pairing")
|
||||
ErrIncorrectEmoji = errors.New("user chose incorrect emoji on phone")
|
||||
ErrPairingCancelled = errors.New("user cancelled pairing on phone")
|
||||
ErrPairingTimeout = errors.New("pairing timed out")
|
||||
ErrPairingInitTimeout = errors.New("client init timed out")
|
||||
)
|
||||
|
||||
const GaiaInitTimeout = 15 * time.Second
|
||||
|
||||
func (c *Client) DoGaiaPairing(ctx context.Context, emojiCallback func(string)) error {
|
||||
if len(c.AuthData.Cookies) == 0 {
|
||||
return ErrNoCookies
|
||||
|
@ -277,12 +281,25 @@ func (c *Client) DoGaiaPairing(ctx context.Context, emojiCallback func(string))
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare pairing payloads: %w", err)
|
||||
}
|
||||
serverInit, err := c.sendGaiaPairingMessage(ctx, ps, gmproto.ActionType_CREATE_GAIA_PAIRING_CLIENT_INIT, clientInit)
|
||||
initCtx, cancel := context.WithTimeout(ctx, GaiaInitTimeout)
|
||||
serverInit, err := c.sendGaiaPairingMessage(initCtx, ps, gmproto.ActionType_CREATE_GAIA_PAIRING_CLIENT_INIT, clientInit)
|
||||
cancel()
|
||||
if err != nil {
|
||||
cancelErr := c.cancelGaiaPairing(ps)
|
||||
if cancelErr != nil {
|
||||
zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to send gaia pairing cancel request after init timeout")
|
||||
}
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
return ErrPairingInitTimeout
|
||||
}
|
||||
return fmt.Errorf("failed to send client init: %w", err)
|
||||
}
|
||||
pairingEmoji, err := ps.ProcessServerInit(serverInit)
|
||||
if err != nil {
|
||||
cancelErr := c.cancelGaiaPairing(ps)
|
||||
if cancelErr != nil {
|
||||
zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to send gaia pairing cancel request after error processing server init")
|
||||
}
|
||||
return fmt.Errorf("error processing server init: %w", err)
|
||||
}
|
||||
emojiCallback(pairingEmoji)
|
||||
|
@ -317,6 +334,16 @@ func (c *Client) DoGaiaPairing(ctx context.Context, emojiCallback func(string))
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) cancelGaiaPairing(sess PairingSession) error {
|
||||
return c.sessionHandler.sendMessageNoResponse(SendMessageParams{
|
||||
Action: gmproto.ActionType_CANCEL_GAIA_PAIRING,
|
||||
RequestID: sess.UUID.String(),
|
||||
DontEncrypt: true,
|
||||
CustomTTL: (300 * time.Second).Microseconds(),
|
||||
MessageType: gmproto.MessageType_GAIA_2,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Client) sendGaiaPairingMessage(ctx context.Context, sess PairingSession, action gmproto.ActionType, msg []byte) (*gmproto.GaiaPairingResponseContainer, error) {
|
||||
respCh, err := c.sessionHandler.sendAsyncMessage(SendMessageParams{
|
||||
Action: action,
|
||||
|
|
|
@ -356,6 +356,11 @@ func (prov *ProvisioningAPI) GoogleLoginStart(w http.ResponseWriter, r *http.Req
|
|||
Error: pairingErrMsgNoDevices,
|
||||
ErrCode: "no-devices-found",
|
||||
})
|
||||
case errors.Is(err, libgm.ErrPairingInitTimeout):
|
||||
jsonResponse(w, http.StatusBadRequest, Error{
|
||||
Error: pairingErrPhoneNotResponding,
|
||||
ErrCode: "timeout",
|
||||
})
|
||||
default:
|
||||
jsonResponse(w, http.StatusInternalServerError, Error{
|
||||
Error: "Failed to start login",
|
||||
|
|
Loading…
Reference in a new issue