mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] Self-serve email change for users (#2957)
* [feature] Email change * frontend stuff for changing email * docs * tests etc * differentiate more clearly between local user+account and account * populate user
This commit is contained in:
@@ -71,9 +71,9 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg *messages.Fro
|
||||
case ap.ActivityCreate:
|
||||
switch cMsg.APObjectType {
|
||||
|
||||
// CREATE PROFILE/ACCOUNT
|
||||
case ap.ObjectProfile, ap.ActorPerson:
|
||||
return p.clientAPI.CreateAccount(ctx, cMsg)
|
||||
// CREATE USER (ie., new user+account sign-up)
|
||||
case ap.ObjectProfile:
|
||||
return p.clientAPI.CreateUser(ctx, cMsg)
|
||||
|
||||
// CREATE NOTE/STATUS
|
||||
case ap.ObjectNote:
|
||||
@@ -111,13 +111,17 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg *messages.Fro
|
||||
case ap.ObjectNote:
|
||||
return p.clientAPI.UpdateStatus(ctx, cMsg)
|
||||
|
||||
// UPDATE PROFILE/ACCOUNT
|
||||
case ap.ObjectProfile, ap.ActorPerson:
|
||||
// UPDATE ACCOUNT (ie., bio, settings, etc)
|
||||
case ap.ActorPerson:
|
||||
return p.clientAPI.UpdateAccount(ctx, cMsg)
|
||||
|
||||
// UPDATE A FLAG/REPORT (mark as resolved/closed)
|
||||
case ap.ActivityFlag:
|
||||
return p.clientAPI.UpdateReport(ctx, cMsg)
|
||||
|
||||
// UPDATE USER (ie., email address)
|
||||
case ap.ObjectProfile:
|
||||
return p.clientAPI.UpdateUser(ctx, cMsg)
|
||||
}
|
||||
|
||||
// ACCEPT SOMETHING
|
||||
@@ -128,9 +132,9 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg *messages.Fro
|
||||
case ap.ActivityFollow:
|
||||
return p.clientAPI.AcceptFollow(ctx, cMsg)
|
||||
|
||||
// ACCEPT PROFILE/ACCOUNT (sign-up)
|
||||
case ap.ObjectProfile, ap.ActorPerson:
|
||||
return p.clientAPI.AcceptAccount(ctx, cMsg)
|
||||
// ACCEPT USER (ie., new user+account sign-up)
|
||||
case ap.ObjectProfile:
|
||||
return p.clientAPI.AcceptUser(ctx, cMsg)
|
||||
}
|
||||
|
||||
// REJECT SOMETHING
|
||||
@@ -141,9 +145,9 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg *messages.Fro
|
||||
case ap.ActivityFollow:
|
||||
return p.clientAPI.RejectFollowRequest(ctx, cMsg)
|
||||
|
||||
// REJECT PROFILE/ACCOUNT (sign-up)
|
||||
case ap.ObjectProfile, ap.ActorPerson:
|
||||
return p.clientAPI.RejectAccount(ctx, cMsg)
|
||||
// REJECT USER (ie., new user+account sign-up)
|
||||
case ap.ObjectProfile:
|
||||
return p.clientAPI.RejectUser(ctx, cMsg)
|
||||
}
|
||||
|
||||
// UNDO SOMETHING
|
||||
@@ -175,17 +179,17 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg *messages.Fro
|
||||
case ap.ObjectNote:
|
||||
return p.clientAPI.DeleteStatus(ctx, cMsg)
|
||||
|
||||
// DELETE PROFILE/ACCOUNT
|
||||
case ap.ObjectProfile, ap.ActorPerson:
|
||||
return p.clientAPI.DeleteAccount(ctx, cMsg)
|
||||
// DELETE REMOTE ACCOUNT or LOCAL USER+ACCOUNT
|
||||
case ap.ActorPerson, ap.ObjectProfile:
|
||||
return p.clientAPI.DeleteAccountOrUser(ctx, cMsg)
|
||||
}
|
||||
|
||||
// FLAG/REPORT SOMETHING
|
||||
case ap.ActivityFlag:
|
||||
switch cMsg.APObjectType { //nolint:gocritic
|
||||
|
||||
// FLAG/REPORT A PROFILE
|
||||
case ap.ObjectProfile:
|
||||
// FLAG/REPORT ACCOUNT
|
||||
case ap.ActorPerson:
|
||||
return p.clientAPI.ReportAccount(ctx, cMsg)
|
||||
}
|
||||
|
||||
@@ -193,8 +197,8 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg *messages.Fro
|
||||
case ap.ActivityMove:
|
||||
switch cMsg.APObjectType { //nolint:gocritic
|
||||
|
||||
// MOVE PROFILE/ACCOUNT
|
||||
case ap.ObjectProfile, ap.ActorPerson:
|
||||
// MOVE ACCOUNT
|
||||
case ap.ActorPerson:
|
||||
return p.clientAPI.MoveAccount(ctx, cMsg)
|
||||
}
|
||||
}
|
||||
@@ -202,7 +206,7 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg *messages.Fro
|
||||
return gtserror.Newf("unhandled: %s %s", cMsg.APActivityType, cMsg.APObjectType)
|
||||
}
|
||||
|
||||
func (p *clientAPI) CreateAccount(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
func (p *clientAPI) CreateUser(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
newUser, ok := cMsg.GTSModel.(*gtsmodel.User)
|
||||
if !ok {
|
||||
return gtserror.Newf("%T not parseable as *gtsmodel.User", cMsg.GTSModel)
|
||||
@@ -219,7 +223,7 @@ func (p *clientAPI) CreateAccount(ctx context.Context, cMsg *messages.FromClient
|
||||
}
|
||||
|
||||
// Send "please confirm your address" email to the new user.
|
||||
if err := p.surface.emailUserPleaseConfirm(ctx, newUser); err != nil {
|
||||
if err := p.surface.emailUserPleaseConfirm(ctx, newUser, true); err != nil {
|
||||
log.Errorf(ctx, "error emailing confirm: %v", err)
|
||||
}
|
||||
|
||||
@@ -479,6 +483,22 @@ func (p *clientAPI) UpdateReport(ctx context.Context, cMsg *messages.FromClientA
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *clientAPI) UpdateUser(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
user, ok := cMsg.GTSModel.(*gtsmodel.User)
|
||||
if !ok {
|
||||
return gtserror.Newf("cannot cast %T -> *gtsmodel.User", cMsg.GTSModel)
|
||||
}
|
||||
|
||||
// The only possible "UpdateUser" action is to update the
|
||||
// user's email address, so we can safely assume by this
|
||||
// point that a new unconfirmed email address has been set.
|
||||
if err := p.surface.emailUserPleaseConfirm(ctx, user, false); err != nil {
|
||||
log.Errorf(ctx, "error emailing report closed: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *clientAPI) AcceptFollow(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
follow, ok := cMsg.GTSModel.(*gtsmodel.Follow)
|
||||
if !ok {
|
||||
@@ -669,7 +689,7 @@ func (p *clientAPI) DeleteStatus(ctx context.Context, cMsg *messages.FromClientA
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *clientAPI) DeleteAccount(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
func (p *clientAPI) DeleteAccountOrUser(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
// The originID of the delete, one of:
|
||||
// - ID of a domain block, for which
|
||||
// this account delete is a side effect.
|
||||
@@ -768,7 +788,7 @@ func (p *clientAPI) MoveAccount(ctx context.Context, cMsg *messages.FromClientAP
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *clientAPI) AcceptAccount(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
func (p *clientAPI) AcceptUser(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
newUser, ok := cMsg.GTSModel.(*gtsmodel.User)
|
||||
if !ok {
|
||||
return gtserror.Newf("%T not parseable as *gtsmodel.User", cMsg.GTSModel)
|
||||
@@ -791,7 +811,7 @@ func (p *clientAPI) AcceptAccount(ctx context.Context, cMsg *messages.FromClient
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *clientAPI) RejectAccount(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
func (p *clientAPI) RejectUser(ctx context.Context, cMsg *messages.FromClientAPI) error {
|
||||
deniedUser, ok := cMsg.GTSModel.(*gtsmodel.DeniedUser)
|
||||
if !ok {
|
||||
return gtserror.Newf("%T not parseable as *gtsmodel.DeniedUser", cMsg.GTSModel)
|
||||
|
@@ -115,8 +115,8 @@ func (p *Processor) ProcessFromFediAPI(ctx context.Context, fMsg *messages.FromF
|
||||
case ap.ObjectNote:
|
||||
return p.fediAPI.UpdateStatus(ctx, fMsg)
|
||||
|
||||
// UPDATE PROFILE/ACCOUNT
|
||||
case ap.ObjectProfile:
|
||||
// UPDATE ACCOUNT
|
||||
case ap.ActorPerson:
|
||||
return p.fediAPI.UpdateAccount(ctx, fMsg)
|
||||
}
|
||||
|
||||
@@ -137,17 +137,17 @@ func (p *Processor) ProcessFromFediAPI(ctx context.Context, fMsg *messages.FromF
|
||||
case ap.ObjectNote:
|
||||
return p.fediAPI.DeleteStatus(ctx, fMsg)
|
||||
|
||||
// DELETE PROFILE/ACCOUNT
|
||||
case ap.ObjectProfile:
|
||||
// DELETE ACCOUNT
|
||||
case ap.ActorPerson:
|
||||
return p.fediAPI.DeleteAccount(ctx, fMsg)
|
||||
}
|
||||
|
||||
// MOVE SOMETHING
|
||||
case ap.ActivityMove:
|
||||
|
||||
// MOVE PROFILE/ACCOUNT
|
||||
// MOVE ACCOUNT
|
||||
// fromfediapi_move.go.
|
||||
if fMsg.APObjectType == ap.ObjectProfile {
|
||||
if fMsg.APObjectType == ap.ActorPerson {
|
||||
return p.fediAPI.MoveAccount(ctx, fMsg)
|
||||
}
|
||||
}
|
||||
|
@@ -337,7 +337,7 @@ func (suite *FromFediAPITestSuite) TestProcessAccountDelete() {
|
||||
|
||||
// now they are mufos!
|
||||
err = testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{
|
||||
APObjectType: ap.ObjectProfile,
|
||||
APObjectType: ap.ActorPerson,
|
||||
APActivityType: ap.ActivityDelete,
|
||||
GTSModel: deletedAccount,
|
||||
Receiving: receivingAccount,
|
||||
@@ -613,7 +613,7 @@ func (suite *FromFediAPITestSuite) TestMoveAccount() {
|
||||
|
||||
// Process the Move.
|
||||
err := testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{
|
||||
APObjectType: ap.ObjectProfile,
|
||||
APObjectType: ap.ActorPerson,
|
||||
APActivityType: ap.ActivityMove,
|
||||
GTSModel: >smodel.Move{
|
||||
OriginURI: requestingAcct.URI,
|
||||
|
@@ -74,7 +74,10 @@ func (s *Surface) emailUserReportClosed(ctx context.Context, report *gtsmodel.Re
|
||||
|
||||
// emailUserPleaseConfirm emails the given user
|
||||
// to ask them to confirm their email address.
|
||||
func (s *Surface) emailUserPleaseConfirm(ctx context.Context, user *gtsmodel.User) error {
|
||||
//
|
||||
// If newSignup is true, template will be geared
|
||||
// towards someone who just created an account.
|
||||
func (s *Surface) emailUserPleaseConfirm(ctx context.Context, user *gtsmodel.User, newSignup bool) error {
|
||||
if user.UnconfirmedEmail == "" ||
|
||||
user.UnconfirmedEmail == user.Email {
|
||||
// User has already confirmed this
|
||||
@@ -104,6 +107,7 @@ func (s *Surface) emailUserPleaseConfirm(ctx context.Context, user *gtsmodel.Use
|
||||
InstanceURL: instance.URI,
|
||||
InstanceName: instance.Title,
|
||||
ConfirmLink: confirmLink,
|
||||
NewSignup: newSignup,
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
|
Reference in New Issue
Block a user