diff --git a/internal/visibility/filter_test.go b/internal/visibility/filter_test.go index 1283a50de..f384f12ff 100644 --- a/internal/visibility/filter_test.go +++ b/internal/visibility/filter_test.go @@ -60,8 +60,8 @@ func (suite *FilterStandardTestSuite) SetupSuite() { } func (suite *FilterStandardTestSuite) SetupTest() { - testrig.InitTestLog() testrig.InitTestConfig() + testrig.InitTestLog() suite.db = testrig.NewTestDB() suite.filter = visibility.NewFilter(suite.db) diff --git a/internal/visibility/statushometimelineable.go b/internal/visibility/statushometimelineable.go index bd3c90b4d..dabb1fa4b 100644 --- a/internal/visibility/statushometimelineable.go +++ b/internal/visibility/statushometimelineable.go @@ -21,17 +21,27 @@ import ( "context" "fmt" + "time" "codeberg.org/gruf/go-kv" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/log" ) func (f *filter) StatusHometimelineable(ctx context.Context, targetStatus *gtsmodel.Status, timelineOwnerAccount *gtsmodel.Account) (bool, error) { - l := log.WithFields(kv.Fields{ + l := log.WithFields(kv.Fields{{"statusID", targetStatus.ID}}...) - {"statusID", targetStatus.ID}, - }...) + // don't timeline statuses more than 5 min in the future + maxID, err := id.NewULIDFromTime(time.Now().Add(5 * time.Minute)) + if err != nil { + return false, err + } + + if targetStatus.ID > maxID { + l.Debug("status not hometimelineable because it's from more than 5 minutes in the future") + return false, nil + } // status owner should always be able to see their own status in their timeline so we can return early if this is the case if targetStatus.AccountID == timelineOwnerAccount.ID { diff --git a/internal/visibility/statushometimelineable_test.go b/internal/visibility/statushometimelineable_test.go index ca80664dc..fc428af5f 100644 --- a/internal/visibility/statushometimelineable_test.go +++ b/internal/visibility/statushometimelineable_test.go @@ -21,10 +21,12 @@ import ( "context" "testing" + "time" "github.com/stretchr/testify/suite" "github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/testrig" ) @@ -65,6 +67,44 @@ func (suite *StatusStatusHometimelineableTestSuite) TestNotFollowingStatusHometi suite.False(timelineable) } +func (suite *StatusStatusHometimelineableTestSuite) TestStatusTooNewNotTimelineable() { + testStatus := >smodel.Status{} + *testStatus = *suite.testStatuses["local_account_1_status_1"] + + var err error + testStatus.ID, err = id.NewULIDFromTime(time.Now().Add(10 * time.Minute)) + if err != nil { + suite.FailNow(err.Error()) + } + + testAccount := suite.testAccounts["local_account_1"] + ctx := context.Background() + + timelineable, err := suite.filter.StatusHometimelineable(ctx, testStatus, testAccount) + suite.NoError(err) + + suite.False(timelineable) +} + +func (suite *StatusStatusHometimelineableTestSuite) TestStatusNotTooNewTimelineable() { + testStatus := >smodel.Status{} + *testStatus = *suite.testStatuses["local_account_1_status_1"] + + var err error + testStatus.ID, err = id.NewULIDFromTime(time.Now().Add(4 * time.Minute)) + if err != nil { + suite.FailNow(err.Error()) + } + + testAccount := suite.testAccounts["local_account_1"] + ctx := context.Background() + + timelineable, err := suite.filter.StatusHometimelineable(ctx, testStatus, testAccount) + suite.NoError(err) + + suite.True(timelineable) +} + func (suite *StatusStatusHometimelineableTestSuite) TestChainReplyFollowersOnly() { ctx := context.Background() diff --git a/internal/visibility/statuspublictimelineable.go b/internal/visibility/statuspublictimelineable.go index 848842225..fb3f4fde1 100644 --- a/internal/visibility/statuspublictimelineable.go +++ b/internal/visibility/statuspublictimelineable.go @@ -21,17 +21,27 @@ import ( "context" "fmt" + "time" "codeberg.org/gruf/go-kv" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/log" ) func (f *filter) StatusPublictimelineable(ctx context.Context, targetStatus *gtsmodel.Status, timelineOwnerAccount *gtsmodel.Account) (bool, error) { - l := log.WithFields(kv.Fields{ + l := log.WithFields(kv.Fields{{"statusID", targetStatus.ID}}...) - {"statusID", targetStatus.ID}, - }...) + // don't timeline statuses more than 5 min in the future + maxID, err := id.NewULIDFromTime(time.Now().Add(5 * time.Minute)) + if err != nil { + return false, err + } + + if targetStatus.ID > maxID { + l.Debug("status not hometimelineable because it's from more than 5 minutes in the future") + return false, nil + } // Don't timeline boosted statuses if targetStatus.BoostOfID != "" { diff --git a/internal/visibility/statusvisible.go b/internal/visibility/statusvisible.go index c62ebb0af..43131410b 100644 --- a/internal/visibility/statusvisible.go +++ b/internal/visibility/statusvisible.go @@ -29,14 +29,10 @@ ) func (f *filter) StatusVisible(ctx context.Context, targetStatus *gtsmodel.Status, requestingAccount *gtsmodel.Account) (bool, error) { - const getBoosted = true - - l := log.WithFields(kv.Fields{ - - {"statusID", targetStatus.ID}, - }...) + l := log.WithFields(kv.Fields{{"statusID", targetStatus.ID}}...) // Fetch any relevant accounts for the target status + const getBoosted = true relevantAccounts, err := f.relevantAccounts(ctx, targetStatus, getBoosted) if err != nil { l.Debugf("error pulling relevant accounts for status %s: %s", targetStatus.ID, err)