Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require (
golang.org/x/net v0.58.0
google.golang.org/protobuf v1.36.12
gopkg.in/yaml.v3 v3.0.1
maunium.net/go/mautrix v0.30.1-0.20260828211758-e9466a65f64c
maunium.net/go/mautrix v0.30.1-0.20260831151715-fe59fad51761
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,5 @@ gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
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/mautrix v0.30.1-0.20260828211758-e9466a65f64c h1:AakW6nCwwg1c3/XKK+M+ikCkt6IGTrzlgrZrVHNBHUA=
maunium.net/go/mautrix v0.30.1-0.20260828211758-e9466a65f64c/go.mod h1:Y02sBiAvfEVqK24bwVGCprmLATRZ7prWel3ZpB413e0=
maunium.net/go/mautrix v0.30.1-0.20260831151715-fe59fad51761 h1:hCXtZ9QLncjZnVAL0ZJ83sFWb7hQhc0qoBEf7DERYnA=
maunium.net/go/mautrix v0.30.1-0.20260831151715-fe59fad51761/go.mod h1:Y02sBiAvfEVqK24bwVGCprmLATRZ7prWel3ZpB413e0=
8 changes: 8 additions & 0 deletions pkg/connector/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,13 @@ func (m *MetaNativeLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error)
return m.proceed(ctx, nil)
}

func (m *MetaNativeLogin) CancelStep(ctx context.Context) (*bridgev2.LoginStep, error) {
if err := m.SavedClient.MessengerLite.CancelLoginStep(ctx); err != nil {
return nil, err
}
return m.proceed(ctx, nil)
}

func (m *MetaNativeLogin) proceed(ctx context.Context, userInput map[string]string) (*bridgev2.LoginStep, error) {
log := zerolog.Ctx(ctx).With().Str("component", "messagix").Logger()

Expand Down Expand Up @@ -370,3 +377,4 @@ func (m *MetaNativeLogin) proceed(ctx context.Context, userInput map[string]stri
var _ bridgev2.LoginProcessUserInput = (*MetaNativeLogin)(nil)
var _ bridgev2.LoginProcessCookies = (*MetaNativeLogin)(nil)
var _ bridgev2.LoginProcessDisplayAndWait = (*MetaNativeLogin)(nil)
var _ bridgev2.LoginProcessStepCancel = (*MetaNativeLogin)(nil)
47 changes: 44 additions & 3 deletions pkg/messagix/bloks/selenium.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ type Browser struct {
AFADNotification string
AFADInterval time.Duration
AFADCallback func() error
MFACanGoBack bool

LoginData string
DisplayedURL string
Expand Down Expand Up @@ -1450,6 +1451,7 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
StepID: b.stepID("otp_code"),
Instructions: instructions,
UserInputParams: &bridgev2.LoginUserInputParams{
CanCancel: b.MFACanGoBack,
Fields: []bridgev2.LoginInputDataField{
{
ID: "otp_code",
Expand Down Expand Up @@ -1517,6 +1519,7 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
StepID: b.stepID("backup_code"),
Instructions: instructions,
UserInputParams: &bridgev2.LoginUserInputParams{
CanCancel: b.MFACanGoBack,
Fields: []bridgev2.LoginInputDataField{
{ID: "backup_code", Name: "Backup code", Type: bridgev2.LoginInputFieldType2FACode},
},
Expand Down Expand Up @@ -1790,6 +1793,7 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)

case StateChooseMFAPage:
foundMethods, methodNames, numIgnored := b.profile.findMFAMethods(b.CurrentPage, log)
b.MFACanGoBack = false

if len(foundMethods) == 0 {
if numIgnored == 0 {
Expand Down Expand Up @@ -1830,6 +1834,7 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
if err != nil {
return nil, b.profile.mfaMethodTapError(chosenMethod, err)
}
b.MFACanGoBack = len(foundMethods) > 1
if !b.profile.shouldContinueAfterMFAMethod(b.State) {
break
}
Expand Down Expand Up @@ -1857,6 +1862,7 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
StepID: b.stepID("totp"),
Instructions: instructions,
UserInputParams: &bridgev2.LoginUserInputParams{
CanCancel: b.MFACanGoBack,
Fields: []bridgev2.LoginInputDataField{
{ID: "totp_code", Name: "Six-digit code", Type: bridgev2.LoginInputFieldType2FACode},
},
Expand Down Expand Up @@ -1957,7 +1963,8 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
StepID: b.stepID("afad_wait"),
Instructions: b.AFADNotification,
DisplayAndWaitParams: &bridgev2.LoginDisplayAndWaitParams{
Type: bridgev2.LoginDisplayTypeNothing,
Type: bridgev2.LoginDisplayTypeNothing,
CanCancel: b.MFACanGoBack,
},
}
b.State = StateAFADPageWaiting
Expand All @@ -1967,10 +1974,19 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
if b.AFADCallback == nil {
return nil, loginerrors.AFADStopped
}
time.Sleep(b.AFADInterval)
select {
case <-time.After(b.AFADInterval):
case <-ctx.Done():
if errors.Is(context.Cause(ctx), bridgev2.ErrLoginStepCancelled) {
return nil, bridgev2.ErrLoginStepCancelled
}
return nil, fmt.Errorf("login cancelled while waiting for approval: %w", ctx.Err())
}
err := b.AFADCallback()
if err != nil {
if ctxErr := ctx.Err(); ctxErr != nil {
if errors.Is(context.Cause(ctx), bridgev2.ErrLoginStepCancelled) {
return nil, bridgev2.ErrLoginStepCancelled
} else if ctxErr := ctx.Err(); ctxErr != nil {
return nil, fmt.Errorf("login cancelled while waiting for approval: %w", ctxErr)
}
return nil, fmt.Errorf("AFAD callback: %w", err)
Expand Down Expand Up @@ -2078,6 +2094,7 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
StepID: b.stepID("sms"),
Instructions: instructions,
UserInputParams: &bridgev2.LoginUserInputParams{
CanCancel: b.MFACanGoBack,
Fields: []bridgev2.LoginInputDataField{
{ID: "sms_code", Name: "Six-digit code", Type: bridgev2.LoginInputFieldType2FACode},
},
Expand Down Expand Up @@ -2220,6 +2237,7 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
StepID: b.stepID("whatsapp"),
Instructions: instructions,
UserInputParams: &bridgev2.LoginUserInputParams{
CanCancel: b.MFACanGoBack,
Fields: []bridgev2.LoginInputDataField{
{ID: "whatsapp_code", Name: "Six-digit code", Type: bridgev2.LoginInputFieldType2FACode},
},
Expand Down Expand Up @@ -2344,6 +2362,29 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string)
return step, nil
}

func (b *Browser) CancelLoginStep(ctx context.Context) error {
if !b.MFACanGoBack {
return fmt.Errorf("current login step cannot be cancelled")
}
switch b.State {
case StateCodeEntryPage, StateBackupCodePage, StateTOTPPage,
StateSMSPageAfterSend, StateWhatsAppPageAfterSend, StateAFADPageWaiting:
default:
return fmt.Errorf("current login step cannot be cancelled")
}
btn := b.CurrentPage.
FindDescendant(FilterByAttribute("bk.data.TextSpan", "text", "Try another way")).
FindContainingButton()
if btn == nil {
return fmt.Errorf("couldn't find try another way button")
}
if err := btn.TapButton(ctx, b.CurrentPage.Interpreter); err != nil {
return fmt.Errorf("tapping try another way button: %w", err)
}
b.MFACanGoBack = false
return nil
}

func authenticationConfirmationPageState(page *BloksBundle) BrowserState {
if page != nil && page.FindDescendant(FilterByComponent("bk.components.TextInput")) != nil {
return StateAccountRecoveryPage
Expand Down
7 changes: 7 additions & 0 deletions pkg/messagix/messengerlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,10 @@ func (m *MessengerLiteMethods) DoLoginSteps(ctx context.Context, userInput map[s

return nil, m.convertCookies(loginRespPayload.SessionCookies), nil
}

func (m *MessengerLiteMethods) CancelLoginStep(ctx context.Context) error {
if m.browser == nil {
return fmt.Errorf("login browser is not initialized")
}
return m.browser.CancelLoginStep(ctx)
}
Loading