Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Hide ignored invites #9255

Closed
wants to merge 1 commit into from
Closed

Conversation

Yoric
Copy link
Contributor

@Yoric Yoric commented Sep 7, 2022

This code is part of an early Proof of Concept for hiding invite spam. The general idea is that rejecting invites doesn't work, because spam bots simply use that rejection to send more invite spam.

The general idea is:

  1. MSC3847 provides a spec for ignoring invites.
  2. matrix-js-sdk PR 2626 implements a filter that determines whether an invite should be ignored.
  3. With this PR, matrix-react-sdk makes use of the filter to hide ignored invites. At this stage, it is possible to ignore invites by modifying state manually, but that's not how it's meant to be used.
  4. A followup PR will add slash commands to semi-easily add/remove/inspect the list of ignored invites, letting power users actually try out the feature.
  5. If that tryout works, the missing bricks will be:
    • a convenient UX to ignore one/many invites;
    • a convenient UX to inspect/un-ignore ignored invites;
    • a mechanism to automatically cleanup ignored invites (and turn them into rejections) after a time;
    • extending this to other clients.

Checklist

  • Tests written for new code (and old code if feasible)
  • Linter and other CI checks pass
  • Sign-off given on the changes (see CONTRIBUTING.md)

Here's what your changelog entry will look like:

✨ Features

@Yoric Yoric requested a review from a team as a code owner September 7, 2022 10:42
@Yoric Yoric marked this pull request as draft September 7, 2022 10:42
@Yoric
Copy link
Contributor Author

Yoric commented Sep 7, 2022

Opening a PR to gather early feedback, but tests haven't been written yet.

@weeman1337 weeman1337 added the T-Enhancement New features, changes in functionality, performance boosts, user-facing improvements label Sep 7, 2022
@weeman1337
Copy link
Contributor

Hey @Yoric 👋 Does this relate to any issue? If so, can you please link it? If not can you describe your changes (from user point of view)?

@Yoric
Copy link
Contributor Author

Yoric commented Sep 7, 2022

Hey @Yoric wave Does this relate to any issue? If so, can you please link it? If not can you describe your changes (from user point of view)?

Oh, right. I've just expanded the description.

@Yoric Yoric marked this pull request as ready for review September 7, 2022 14:34
With this PR, invites that are specified by MSC3847 to be ignored are hidden.
@Yoric
Copy link
Contributor Author

Yoric commented Sep 7, 2022

Opening a PR to gather early feedback, but tests haven't been written yet.

Now with tests.

@Yoric
Copy link
Contributor Author

Yoric commented Sep 7, 2022

Not sure what's wrong with Static Analysis. All the errors it shows me are in parts of the code that I'm not hitting. Furthermore, yarn lint doesn't show any error for me when run locally.

Same for yarn test --coverage.

Comment on lines +166 to +171
private async updateStickyRoom(val: Room) {
await this.doUpdateStickyRoom(val);
this._lastStickyRoom = null; // clear to indicate we're done changing
}

private doUpdateStickyRoom(val: Room) {
private async doUpdateStickyRoom(val: Room) {
Copy link
Member

@t3chguy t3chguy Sep 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These cannot be async, this causes race conditions, please see git history around this file. You would need to introduce a semaphore to prevent updates racing with each other.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g. #6391

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch. Will do, thanks!

@@ -38,7 +39,7 @@ export class VisibilityProvider {
await VoipUserMapper.sharedInstance().onNewInvitedRoom(room);
}

public isRoomVisible(room?: Room): boolean {
public async isRoomVisible(room?: Room): Promise<boolean> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change, existing customisations will fail to compile with this change due to the return type changing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would you suggest?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move it into the js-sdk as a background operation, so consumers don't have to make all their APIs async. Feels a bit strange for getRuleForInvite to be an async function which actually creates rooms, it seems like that one should be read-only, and something else should create and uphold the policy rooms, emitting "PolicyUpdated" or similar events for consumers to subscribe and react to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also looks like getOrCreateTargetRoom is flawed if called multiple times whilst the room is being created, it'll stack multiple creations instead of being idempotent. This could also occur with this PR where multiple operations overlap and call isRoomVisible causing overlapping calls to getOrCreateTargetRoom

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also looks like getOrCreateTargetRoom is flawed if called multiple times whilst the room is being created, it'll stack multiple creations instead of being idempotent. This could also occur with this PR where multiple operations overlap and call isRoomVisible causing overlapping calls to getOrCreateTargetRoom

You're right, I should at least lock it to avoid that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move it into the js-sdk as a background operation, so consumers don't have to make all their APIs async. Feels a bit strange for getRuleForInvite to be an async function which actually creates rooms, it seems like that one should be read-only, and something else should create and uphold the policy rooms, emitting "PolicyUpdated" or similar events for consumers to subscribe and react to.

That was the design at some point but I dropped it because it felt like I would be reimplementing a non-trivial subset of the state event store. On the other hand, it is probably needed to achieve any kind of performance anyway, so now might be the right time to revisit this.

I'll think this over.

Copy link
Contributor Author

@Yoric Yoric Sep 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case someone else reads this, this conversation has spawned a patch in matrix-js-sdk: matrix-org/matrix-js-sdk#2653 .

@Yoric Yoric marked this pull request as draft September 7, 2022 14:49
Yoric added a commit to Yoric/matrix-js-sdk that referenced this pull request Sep 8, 2022
Experience and feedback from matrix-org/matrix-react-sdk#9255
indicates that we cannot integrate an async `IgnoredInvites.getRuleForInvite`. This
PR:

- rewrites `getRuleForInvite` to be sync;
- adds some locking within `IgnoredInvites` to avoid race conditions noticed by @t3chguy.
Yoric added a commit to Yoric/matrix-js-sdk that referenced this pull request Nov 3, 2022
Experience and feedback from matrix-org/matrix-react-sdk#9255
indicates that we cannot integrate an async `IgnoredInvites.getRuleForInvite`. This
PR:

- rewrites `getRuleForInvite` to be sync;
- adds some locking within `IgnoredInvites` to avoid race conditions noticed by @t3chguy.
@langleyd langleyd closed this Sep 11, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
T-Enhancement New features, changes in functionality, performance boosts, user-facing improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants