summaryrefslogtreecommitdiff
path: root/internal/processing/workers/fromfediapi.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/processing/workers/fromfediapi.go')
-rw-r--r--internal/processing/workers/fromfediapi.go170
1 files changed, 113 insertions, 57 deletions
diff --git a/internal/processing/workers/fromfediapi.go b/internal/processing/workers/fromfediapi.go
index ce7c53388..908369ca6 100644
--- a/internal/processing/workers/fromfediapi.go
+++ b/internal/processing/workers/fromfediapi.go
@@ -20,18 +20,22 @@ package workers
import (
"context"
"errors"
+ "time"
"codeberg.org/gruf/go-kv"
"codeberg.org/gruf/go-logger/v2/level"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
+ "github.com/superseriousbusiness/gotosocial/internal/id"
+ "github.com/superseriousbusiness/gotosocial/internal/uris"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/log"
"github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/processing/account"
+ "github.com/superseriousbusiness/gotosocial/internal/processing/common"
"github.com/superseriousbusiness/gotosocial/internal/state"
"github.com/superseriousbusiness/gotosocial/internal/util"
)
@@ -44,6 +48,7 @@ type fediAPI struct {
surface *Surface
federate *federate
account *account.Processor
+ common *common.Processor
utils *utils
}
@@ -231,10 +236,7 @@ func (p *fediAPI) CreateStatus(ctx context.Context, fMsg *messages.FromFediAPI)
// If pending approval is true then
// status must reply to a LOCAL status
// that requires approval for the reply.
- pendingApproval := util.PtrOrValue(
- status.PendingApproval,
- false,
- )
+ pendingApproval := util.PtrOrZero(status.PendingApproval)
switch {
case pendingApproval && !status.PreApproved:
@@ -242,10 +244,8 @@ func (p *fediAPI) CreateStatus(ctx context.Context, fMsg *messages.FromFediAPI)
// preapproved, then just notify the account
// that's being interacted with: they can
// approve or deny the interaction later.
-
- // Notify *local* account of pending reply.
- if err := p.surface.notifyPendingReply(ctx, status); err != nil {
- log.Errorf(ctx, "error notifying pending reply: %v", err)
+ if err := p.utils.requestReply(ctx, status); err != nil {
+ return gtserror.Newf("error pending reply: %w", err)
}
// Return early.
@@ -259,11 +259,33 @@ func (p *fediAPI) CreateStatus(ctx context.Context, fMsg *messages.FromFediAPI)
// collection. Do the Accept immediately and
// then process everything else as normal.
- // Put approval in the database and
- // update the status with approvedBy URI.
- approval, err := p.utils.approveReply(ctx, status)
- if err != nil {
- return gtserror.Newf("error pre-approving reply: %w", err)
+ // Store an already-accepted interaction request.
+ id := id.NewULID()
+ approval := &gtsmodel.InteractionRequest{
+ ID: id,
+ StatusID: status.InReplyToID,
+ TargetAccountID: status.InReplyToAccountID,
+ TargetAccount: status.InReplyToAccount,
+ InteractingAccountID: status.AccountID,
+ InteractingAccount: status.Account,
+ InteractionURI: status.URI,
+ InteractionType: gtsmodel.InteractionLike,
+ Reply: status,
+ URI: uris.GenerateURIForAccept(status.InReplyToAccount.Username, id),
+ AcceptedAt: time.Now(),
+ }
+
+ // Mark the status as now approved.
+ status.PendingApproval = util.Ptr(false)
+ status.PreApproved = false
+ status.ApprovedByURI = approval.URI
+ if err := p.state.DB.UpdateStatus(
+ ctx,
+ status,
+ "pending_approval",
+ "approved_by_uri",
+ ); err != nil {
+ return gtserror.Newf("db error updating status: %w", err)
}
// Send out the approval as Accept.
@@ -279,6 +301,10 @@ func (p *fediAPI) CreateStatus(ctx context.Context, fMsg *messages.FromFediAPI)
log.Errorf(ctx, "error updating account stats: %v", err)
}
+ if err := p.surface.timelineAndNotifyStatus(ctx, status); err != nil {
+ log.Errorf(ctx, "error timelining and notifying status: %v", err)
+ }
+
if status.InReplyToID != "" {
// Interaction counts changed on the replied status; uncache the
// prepared version from all timelines. The status dereferencer
@@ -286,10 +312,6 @@ func (p *fediAPI) CreateStatus(ctx context.Context, fMsg *messages.FromFediAPI)
p.surface.invalidateStatusFromTimelines(ctx, status.InReplyToID)
}
- if err := p.surface.timelineAndNotifyStatus(ctx, status); err != nil {
- log.Errorf(ctx, "error timelining and notifying status: %v", err)
- }
-
return nil
}
@@ -320,9 +342,6 @@ func (p *fediAPI) CreatePollVote(ctx context.Context, fMsg *messages.FromFediAPI
status := vote.Poll.Status
status.Poll = vote.Poll
- // Interaction counts changed on the source status, uncache from timelines.
- p.surface.invalidateStatusFromTimelines(ctx, vote.Poll.StatusID)
-
if *status.Local {
// Before federating it, increment the
// poll vote counts on our local copy.
@@ -335,6 +354,9 @@ func (p *fediAPI) CreatePollVote(ctx context.Context, fMsg *messages.FromFediAPI
}
}
+ // Interaction counts changed on the source status, uncache from timelines.
+ p.surface.invalidateStatusFromTimelines(ctx, vote.Poll.StatusID)
+
return nil
}
@@ -409,10 +431,7 @@ func (p *fediAPI) CreateLike(ctx context.Context, fMsg *messages.FromFediAPI) er
// If pending approval is true then
// fave must target a LOCAL status
// that requires approval for the fave.
- pendingApproval := util.PtrOrValue(
- fave.PendingApproval,
- false,
- )
+ pendingApproval := util.PtrOrZero(fave.PendingApproval)
switch {
case pendingApproval && !fave.PreApproved:
@@ -420,10 +439,8 @@ func (p *fediAPI) CreateLike(ctx context.Context, fMsg *messages.FromFediAPI) er
// preapproved, then just notify the account
// that's being interacted with: they can
// approve or deny the interaction later.
-
- // Notify *local* account of pending fave.
- if err := p.surface.notifyPendingFave(ctx, fave); err != nil {
- log.Errorf(ctx, "error notifying pending fave: %v", err)
+ if err := p.utils.requestFave(ctx, fave); err != nil {
+ return gtserror.Newf("error pending fave: %w", err)
}
// Return early.
@@ -437,11 +454,33 @@ func (p *fediAPI) CreateLike(ctx context.Context, fMsg *messages.FromFediAPI) er
// collection. Do the Accept immediately and
// then process everything else as normal.
- // Put approval in the database and
- // update the fave with approvedBy URI.
- approval, err := p.utils.approveFave(ctx, fave)
- if err != nil {
- return gtserror.Newf("error pre-approving fave: %w", err)
+ // Store an already-accepted interaction request.
+ id := id.NewULID()
+ approval := &gtsmodel.InteractionRequest{
+ ID: id,
+ StatusID: fave.StatusID,
+ TargetAccountID: fave.TargetAccountID,
+ TargetAccount: fave.TargetAccount,
+ InteractingAccountID: fave.AccountID,
+ InteractingAccount: fave.Account,
+ InteractionURI: fave.URI,
+ InteractionType: gtsmodel.InteractionLike,
+ Like: fave,
+ URI: uris.GenerateURIForAccept(fave.TargetAccount.Username, id),
+ AcceptedAt: time.Now(),
+ }
+
+ // Mark the fave itself as now approved.
+ fave.PendingApproval = util.Ptr(false)
+ fave.PreApproved = false
+ fave.ApprovedByURI = approval.URI
+ if err := p.state.DB.UpdateStatusFave(
+ ctx,
+ fave,
+ "pending_approval",
+ "approved_by_uri",
+ ); err != nil {
+ return gtserror.Newf("db error updating status fave: %w", err)
}
// Send out the approval as Accept.
@@ -496,10 +535,7 @@ func (p *fediAPI) CreateAnnounce(ctx context.Context, fMsg *messages.FromFediAPI
// If pending approval is true then
// boost must target a LOCAL status
// that requires approval for the boost.
- pendingApproval := util.PtrOrValue(
- boost.PendingApproval,
- false,
- )
+ pendingApproval := util.PtrOrZero(boost.PendingApproval)
switch {
case pendingApproval && !boost.PreApproved:
@@ -507,10 +543,8 @@ func (p *fediAPI) CreateAnnounce(ctx context.Context, fMsg *messages.FromFediAPI
// preapproved, then just notify the account
// that's being interacted with: they can
// approve or deny the interaction later.
-
- // Notify *local* account of pending announce.
- if err := p.surface.notifyPendingAnnounce(ctx, boost); err != nil {
- log.Errorf(ctx, "error notifying pending boost: %v", err)
+ if err := p.utils.requestAnnounce(ctx, boost); err != nil {
+ return gtserror.Newf("error pending boost: %w", err)
}
// Return early.
@@ -524,11 +558,33 @@ func (p *fediAPI) CreateAnnounce(ctx context.Context, fMsg *messages.FromFediAPI
// collection. Do the Accept immediately and
// then process everything else as normal.
- // Put approval in the database and
- // update the boost with approvedBy URI.
- approval, err := p.utils.approveAnnounce(ctx, boost)
- if err != nil {
- return gtserror.Newf("error pre-approving boost: %w", err)
+ // Store an already-accepted interaction request.
+ id := id.NewULID()
+ approval := &gtsmodel.InteractionRequest{
+ ID: id,
+ StatusID: boost.BoostOfID,
+ TargetAccountID: boost.BoostOfAccountID,
+ TargetAccount: boost.BoostOfAccount,
+ InteractingAccountID: boost.AccountID,
+ InteractingAccount: boost.Account,
+ InteractionURI: boost.URI,
+ InteractionType: gtsmodel.InteractionLike,
+ Announce: boost,
+ URI: uris.GenerateURIForAccept(boost.BoostOfAccount.Username, id),
+ AcceptedAt: time.Now(),
+ }
+
+ // Mark the boost itself as now approved.
+ boost.PendingApproval = util.Ptr(false)
+ boost.PreApproved = false
+ boost.ApprovedByURI = approval.URI
+ if err := p.state.DB.UpdateStatus(
+ ctx,
+ boost,
+ "pending_approval",
+ "approved_by_uri",
+ ); err != nil {
+ return gtserror.Newf("db error updating status: %w", err)
}
// Send out the approval as Accept.
@@ -729,15 +785,15 @@ func (p *fediAPI) AcceptReply(ctx context.Context, fMsg *messages.FromFediAPI) e
log.Errorf(ctx, "error timelining and notifying status: %v", err)
}
- // Interaction counts changed on the replied-to status;
- // uncache the prepared version from all timelines.
- p.surface.invalidateStatusFromTimelines(ctx, status.InReplyToID)
-
// Send out the reply again, fully this time.
if err := p.federate.CreateStatus(ctx, status); err != nil {
log.Errorf(ctx, "error federating announce: %v", err)
}
+ // Interaction counts changed on the replied-to status;
+ // uncache the prepared version from all timelines.
+ p.surface.invalidateStatusFromTimelines(ctx, status.InReplyToID)
+
return nil
}
@@ -757,15 +813,15 @@ func (p *fediAPI) AcceptAnnounce(ctx context.Context, fMsg *messages.FromFediAPI
log.Errorf(ctx, "error timelining and notifying status: %v", err)
}
- // Interaction counts changed on the boosted status;
- // uncache the prepared version from all timelines.
- p.surface.invalidateStatusFromTimelines(ctx, boost.BoostOfID)
-
// Send out the boost again, fully this time.
if err := p.federate.Announce(ctx, boost); err != nil {
log.Errorf(ctx, "error federating announce: %v", err)
}
+ // Interaction counts changed on the boosted status;
+ // uncache the prepared version from all timelines.
+ p.surface.invalidateStatusFromTimelines(ctx, boost.BoostOfID)
+
return nil
}
@@ -792,9 +848,6 @@ func (p *fediAPI) UpdateStatus(ctx context.Context, fMsg *messages.FromFediAPI)
log.Errorf(ctx, "error refreshing status: %v", err)
}
- // Status representation was refetched, uncache from timelines.
- p.surface.invalidateStatusFromTimelines(ctx, status.ID)
-
if status.Poll != nil && status.Poll.Closing {
// If the latest status has a newly closed poll, at least compared
@@ -809,6 +862,9 @@ func (p *fediAPI) UpdateStatus(ctx context.Context, fMsg *messages.FromFediAPI)
log.Errorf(ctx, "error streaming status edit: %v", err)
}
+ // Status representation was refetched, uncache from timelines.
+ p.surface.invalidateStatusFromTimelines(ctx, status.ID)
+
return nil
}