Refactor to reuse UserInput step type
Some checks are pending
Go / Lint (latest) (push) Waiting to run
Go / Build (old, libolm) (push) Waiting to run
Go / Build (latest, libolm) (push) Waiting to run
Go / Build (old, goolm) (push) Waiting to run
Go / Build (latest, goolm) (push) Waiting to run

This commit is contained in:
Radon Rosborough 2026-02-23 13:04:48 -08:00
commit 6183dda6f2
2 changed files with 20 additions and 67 deletions

View file

@ -274,32 +274,15 @@ func sendQR(ce *Event, qr string, prevEventID *id.EventID) error {
return nil
}
func sendCaptcha(ce *Event, params *bridgev2.LoginCaptchaParams) error {
if params.ImageMimeType != "" {
filename := "captcha" + exmime.ExtensionFromMimetype(params.ImageMimeType)
mxc, file, err := ce.Bot.UploadMedia(ce.Ctx, ce.RoomID, params.ImageData, filename, params.ImageMimeType)
func sendUserInputAttachments(ce *Event, atts []*bridgev2.LoginUserInputAttachment) error {
for _, att := range atts {
filename := "captcha" + exmime.ExtensionFromMimetype(att.MimeType)
mxc, file, err := ce.Bot.UploadMedia(ce.Ctx, ce.RoomID, att.Content, filename, att.MimeType)
if err != nil {
return fmt.Errorf("failed to upload image: %w", err)
return fmt.Errorf("failed to upload attachment %q: %w", filename, err)
}
content := &event.MessageEventContent{
MsgType: event.MsgImage,
FileName: filename,
URL: mxc,
File: file,
}
_, err = ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventMessage, &event.Content{Parsed: content}, nil)
if err != nil {
return nil
}
}
if params.AudioMimeType != "" {
filename := "captcha" + exmime.ExtensionFromMimetype(params.AudioMimeType)
mxc, file, err := ce.Bot.UploadMedia(ce.Ctx, ce.RoomID, params.AudioData, filename, params.AudioMimeType)
if err != nil {
return fmt.Errorf("failed to upload audio: %w", err)
}
content := &event.MessageEventContent{
MsgType: event.MsgAudio,
MsgType: att.Type,
FileName: filename,
URL: mxc,
File: file,
@ -502,31 +485,6 @@ func maybeURLDecodeCookie(val string, field *bridgev2.LoginCookieField) string {
return decoded
}
type captchaLoginCommandState struct {
Login bridgev2.LoginProcessCaptcha
Data *bridgev2.LoginCaptchaParams
Override *bridgev2.UserLogin
}
func (clcs *captchaLoginCommandState) prompt(ce *Event) {
ce.Reply("Please enter the captcha code")
StoreCommandState(ce.User, &CommandState{
Next: MinimalCommandHandlerFunc(clcs.submit),
Action: "Login",
Meta: clcs,
Cancel: clcs.Login.Cancel,
})
}
func (clcs *captchaLoginCommandState) submit(ce *Event) {
StoreCommandState(ce.User, nil)
if nextStep, err := clcs.Login.SubmitCaptcha(ce.Ctx, ce.RawArgs); err != nil {
ce.Reply("Failed to submit captcha: %v", err)
} else {
doLoginStep(ce, clcs.Login, nextStep, clcs.Override)
}
}
func doLoginStep(ce *Event, login bridgev2.LoginProcess, step *bridgev2.LoginStep, override *bridgev2.UserLogin) {
if step.Instructions != "" {
ce.Reply(step.Instructions)
@ -542,24 +500,16 @@ func doLoginStep(ce *Event, login bridgev2.LoginProcess, step *bridgev2.LoginSte
Override: override,
}).prompt(ce)
case bridgev2.LoginStepTypeUserInput:
err := sendUserInputAttachments(ce, step.UserInputParams.Attachments)
if err != nil {
ce.Reply("Failed to send attachments: %v", err)
}
(&userInputLoginCommandState{
Login: login.(bridgev2.LoginProcessUserInput),
RemainingFields: step.UserInputParams.Fields,
Data: make(map[string]string),
Override: override,
}).promptNext(ce)
case bridgev2.LoginStepTypeCaptcha:
err := sendCaptcha(ce, step.CaptchaParams)
if err != nil {
ce.Reply("Failed to send captcha: %v", err)
login.Cancel()
return
}
(&captchaLoginCommandState{
Login: login.(bridgev2.LoginProcessCaptcha),
Data: step.CaptchaParams,
Override: override,
}).prompt(ce)
case bridgev2.LoginStepTypeComplete:
if override != nil && override.ID != step.CompleteParams.UserLoginID {
ce.Log.Info().

View file

@ -13,6 +13,7 @@ import (
"strings"
"maunium.net/go/mautrix/bridgev2/networkid"
"maunium.net/go/mautrix/event"
)
// LoginProcess represents a single occurrence of a user logging into the remote network.
@ -105,7 +106,6 @@ type LoginStep struct {
DisplayAndWaitParams *LoginDisplayAndWaitParams `json:"display_and_wait,omitempty"`
CookiesParams *LoginCookiesParams `json:"cookies,omitempty"`
UserInputParams *LoginUserInputParams `json:"user_input,omitempty"`
CaptchaParams *LoginCaptchaParams `json:"captcha,omitempty"`
CompleteParams *LoginCompleteParams `json:"complete,omitempty"`
}
@ -186,6 +186,7 @@ const (
LoginInputFieldTypeURL LoginInputFieldType = "url"
LoginInputFieldTypeDomain LoginInputFieldType = "domain"
LoginInputFieldTypeSelect LoginInputFieldType = "select"
LoginInputFieldTypeCaptchaCode LoginInputFieldType = "captcha_code"
)
type LoginInputDataField struct {
@ -278,14 +279,16 @@ func (f *LoginInputDataField) FillDefaultValidate() {
type LoginUserInputParams struct {
// The fields that the user needs to fill in.
Fields []LoginInputDataField `json:"fields"`
// Attachments to display alongside the input fields.
Attachments []*LoginUserInputAttachment `json:"attachments"`
}
type LoginCaptchaParams struct {
ImageData []byte `json:"image,omitempty"`
ImageMimeType string `json:"image_content_type"`
AudioData []byte `json:"audio,omitempty"`
AudioMimeType string `json:"audio_content_type,omitempty"`
type LoginUserInputAttachment struct {
Type event.MessageType
Filename string
MimeType string
Content []byte
}
type LoginCompleteParams struct {