diff options
Diffstat (limited to 'internal/api/client/accounts')
-rw-r--r-- | internal/api/client/accounts/accountupdate.go | 35 | ||||
-rw-r--r-- | internal/api/client/accounts/accountupdate_test.go | 7 |
2 files changed, 40 insertions, 2 deletions
diff --git a/internal/api/client/accounts/accountupdate.go b/internal/api/client/accounts/accountupdate.go index b5d0dd5f9..55e544298 100644 --- a/internal/api/client/accounts/accountupdate.go +++ b/internal/api/client/accounts/accountupdate.go @@ -25,6 +25,7 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/go-playground/form/v4" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" "github.com/superseriousbusiness/gotosocial/internal/gtserror" @@ -115,6 +116,13 @@ import ( // in: formData // description: Enable RSS feed for this account's Public posts at `/[username]/feed.rss` // type: boolean +// - +// name: fields_attributes +// in: formData +// description: Profile fields to be added to this account's profile +// type: array +// items: +// type: object // // security: // - OAuth2 Bearer: @@ -162,6 +170,28 @@ func (m *Module) AccountUpdateCredentialsPATCHHandler(c *gin.Context) { c.JSON(http.StatusOK, acctSensitive) } +type fieldAttributesBinding struct{} + +func (fieldAttributesBinding) Name() string { + return "FieldAttributes" +} + +func (fieldAttributesBinding) Bind(req *http.Request, obj any) error { + if err := req.ParseForm(); err != nil { + return err + } + + decoder := form.NewDecoder() + // change default namespace prefix and suffix to allow correct parsing of the field attributes + decoder.SetNamespacePrefix("[") + decoder.SetNamespaceSuffix("]") + if err := decoder.Decode(obj, req.Form); err != nil { + return err + } + + return nil +} + func parseUpdateAccountForm(c *gin.Context) (*apimodel.UpdateCredentialsRequest, error) { form := &apimodel.UpdateCredentialsRequest{ Source: &apimodel.UpdateSource{}, @@ -171,6 +201,11 @@ func parseUpdateAccountForm(c *gin.Context) (*apimodel.UpdateCredentialsRequest, return nil, fmt.Errorf("could not parse form from request: %s", err) } + // use custom form binding to support field attributes in the form data + if err := c.ShouldBindWith(&form, fieldAttributesBinding{}); err != nil { + return nil, fmt.Errorf("could not parse form from request: %s", err) + } + // parse source field-by-field sourceMap := c.PostFormMap("source") diff --git a/internal/api/client/accounts/accountupdate_test.go b/internal/api/client/accounts/accountupdate_test.go index f898e64da..4e4e03fa4 100644 --- a/internal/api/client/accounts/accountupdate_test.go +++ b/internal/api/client/accounts/accountupdate_test.go @@ -38,12 +38,14 @@ type AccountUpdateTestSuite struct { func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandler() { // set up the request - // we're updating the note of zork + // we're updating the note and profile fields of zork newBio := "this is my new bio read it and weep" requestBody, w, err := testrig.CreateMultipartFormData( "", "", map[string]string{ - "note": newBio, + "note": newBio, + "fields_attributes[0][name]": "pronouns", + "fields_attributes[0][value]": "they/them", }) if err != nil { panic(err) @@ -74,6 +76,7 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandler() // check the returned api model account // fields should be updated suite.Equal("<p>this is my new bio read it and weep</p>", apimodelAccount.Note) + suite.Equal("they/them", apimodelAccount.Fields[0].Value) suite.Equal(newBio, apimodelAccount.Source.Note) } |