Skip to content

MSC4076: Let E2EE clients calculate app badge counts themselves (disable_badge_count)#4076

Open
ara4n wants to merge 11 commits intomainfrom
matthew/msc4076
Open

MSC4076: Let E2EE clients calculate app badge counts themselves (disable_badge_count)#4076
ara4n wants to merge 11 commits intomainfrom
matthew/msc4076

Conversation

@ara4n
Copy link
Copy Markdown
Member

@ara4n ara4n commented Nov 12, 2023

This gives a way for E2EE-aware clients to accurately maintain their own app badge counts, rather than having the server incorrectly override them based on partial information.

Solves element-hq/element-x-ios#3151

Rendered

Implementations:

@turt2live turt2live added push proposal A matrix spec change proposal client-server Client-Server API kind:maintenance MSC which clarifies/updates existing spec needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. labels Nov 12, 2023
Comment thread proposals/4076-e2ee-aware-badges.md Outdated
@@ -0,0 +1,127 @@
# MSC4076: Let E2EE clients calculate app badge counts themselves
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I fail to see how you couldn't already calculate them clientside?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Agreed. TBH I've only skimmed this, but I don't entirely follow why this MSC is necessary for clients to calculate their own badge counts.

(You might justifiably argue that the counts should be removed on the grounds of redundancy, but that doesn't appear to be what this MSC is saying?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You can and should calculate them clientside. However, the server currently overrides them and there is no way to stop the server from doing that, prior to this MSC.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Clearly some crucial information is missing here? Since to my understanding you can just make either fully ignore the server response and do it without it or have an if case for only e2ee rooms. I don't see how that currently impossible? The server isn't demanding a particular execution path on the client obviously?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

However, the server currently overrides them and there is no way to stop the server from doing that, prior to this MSC.

Is this done at the OS-level and the server needs to not include that information to not fight the client doing it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Is this done at the OS-level and the server needs to not include that information to not fight the client doing it?

yes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(this is why literally the first sentence in the proposal is explaining this behaviour and linking to the apple documentation that describes it)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This has come up again, so even though the answer is kinda there in the first sentence and footnote, I don't think hit has been satisfactorily resolved.

I'd suggest rephrasing the introduction to give a bit of background for those who can't remember whether the A in APNS means "Apple" or "Android", far less how APNS actually works.

Apple push notification service (APNS) allows the badge count on applications to be updated based on a field in push notifications, without the application running any code (see APNS documentation). Push notifications in Matrix currently use this property; however, its behaviour in encrypted clients is unsatisfactory due to the following reasons:

  • ... etc

Comment thread proposals/4076-e2ee-aware-badges.md Outdated
Comment thread proposals/4076-e2ee-aware-badges.md Outdated
@manuroe manuroe changed the title MSC4076: Let E2EE clients calculate app & E2EE-room badge counts themselves MSC4076: Let E2EE clients calculate app badge counts themselves (disable_badge_count) Nov 29, 2024
@manuroe
Copy link
Copy Markdown
Contributor

manuroe commented Nov 29, 2024

Synapse PR: element-hq/synapse#17975

It removes the parent counts field as proposed in #4076 (comment). I will undraft the PR once we agree on the spec.

@ara4n ara4n removed the needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. label Nov 29, 2024
@ara4n
Copy link
Copy Markdown
Member Author

ara4n commented Dec 1, 2024

I will undraft the PR once we agree on the spec.

I am not seeing any disagreements on the spec? There is no reason for the PR to be draft if you think it's good for review. The only thing stopping FCP on this MSC right now is the lack of implementation, so please don't block the implementations on the MSC getting FCP'd ;)

@manuroe
Copy link
Copy Markdown
Contributor

manuroe commented Dec 2, 2024

I will undraft the PR once we agree on the spec.

I am not seeing any disagreements on the spec? There is no reason for the PR to be draft if you think it's good for review. The only thing stopping FCP on this MSC right now is the lack of implementation, so please don't block the implementations on the MSC getting FCP'd ;)

I wanted to have a Synapse PR that matches the MSC. With your last commit on this MSC, the Synapse PR can be reviewed. Thanks!

rooms with invisible events) - and at worst will race and fight[^2] with the app badge count maintained locally by the
app, if any.

Therefore we need a way for sophisticated E2EE clients to tell the server to stop overriding their app badge count.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This document doesn't answer what feels like a fair question to have: Why do the sophisticated E2EE clients not just ignore the count?

My presumption is that this is done at the OS-level and the app does not get the choice?

So the next point might be: is this MSC really superior to performing this filtering in the application-specific push gateway (Sygnal) like many other such platform-specific quirks, which already have configuration options?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yes, it's done at the OS level, so the app doesn't get the choice.

I'm not aware of a standard way to configure push gateways for clients in general to say "please don't try to override the app badge count" - wouldn't doing it in a generic way end up being precisely the same as this MSC?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The difference is that the application developer is the one deploying Sygnal, therefore they can do whatever they want in the 'last mile' between Sygnal and their application. If that means Element configures their Sygnal so that it doesn't ship badge counts to Element iOS clients, then there's no particular reason anyone else needs to be involved.
To me, it feels like a better fit for a platform-specific quirk.

Copy link
Copy Markdown
Member

@richvdh richvdh Oct 6, 2025

Choose a reason for hiding this comment

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

This document doesn't answer what feels like a fair question to have: Why do the sophisticated E2EE clients not just ignore the count?

(comment moved to #4076 (comment) to make way for discussion about whether this field is necessary)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The difference is that the application developer is the one deploying Sygnal, therefore they can do whatever they want in the 'last mile' between Sygnal and their application. If that means Element configures their Sygnal so that it doesn't ship badge counts to Element iOS clients, then there's no particular reason anyone else needs to be involved.
To me, it feels like a better fit for a platform-specific quirk.

Emphatic +1 to this. Currently, Sygnal is actively copying the counts.unread field into the right place in the push notification payload. If we now feel that this is inappropriate for Element apps then... just don't do that? Sygnal already has all the information it needs to make this decision; we don't need to complicate the C-S API, homeservers, and Push Gateway API by bouncing it through Synapse.

anoadragon453 pushed a commit to element-hq/synapse that referenced this pull request Dec 3, 2024
This PR implements [MSC4076: Let E2EE clients calculate app badge counts
themselves
(disable_badge_count)](matrix-org/matrix-spec-proposals#4076).
yingziwu added a commit to yingziwu/synapse that referenced this pull request Dec 20, 2024
This release contains the security fixes from [v1.120.2](https://github.com/element-hq/synapse/releases/tag/v1.120.2).

- Fix release process to not create duplicate releases. ([\#18025](element-hq/synapse#18025))

- Support for [MSC4190](matrix-org/matrix-spec-proposals#4190): device management for Application Services. ([\#17705](element-hq/synapse#17705))
- Update [MSC4186](matrix-org/matrix-spec-proposals#4186) Sliding Sync to include invite, ban, kick, targets when `$LAZY`-loading room members. ([\#17947](element-hq/synapse#17947))
- Use stable `M_USER_LOCKED` error code for locked accounts, as per [Matrix 1.12](https://spec.matrix.org/v1.12/client-server-api/#account-locking). ([\#17965](element-hq/synapse#17965))
- [MSC4076](matrix-org/matrix-spec-proposals#4076): Add `disable_badge_count` to pusher configuration. ([\#17975](element-hq/synapse#17975))

- Fix long-standing bug where read receipts could get overly delayed being sent over federation. ([\#17933](element-hq/synapse#17933))

- Add OIDC example configuration for Forgejo (fork of Gitea). ([\#17872](element-hq/synapse#17872))
- Link to element-docker-demo from contrib/docker*. ([\#17953](element-hq/synapse#17953))

- [MSC4108](matrix-org/matrix-spec-proposals#4108): Add a `Content-Type` header on the `PUT` response to work around a faulty behavior in some caching reverse proxies. ([\#17253](element-hq/synapse#17253))
- Fix incorrect comment in new schema delta. ([\#17936](element-hq/synapse#17936))
- Raise setuptools_rust version cap to 1.10.2. ([\#17944](element-hq/synapse#17944))
- Enable encrypted appservice related experimental features in the complement docker image. ([\#17945](element-hq/synapse#17945))
- Return whether the user is suspended when querying the user account in the Admin API. ([\#17952](element-hq/synapse#17952))
- Fix new scheduled tasks jumping the queue. ([\#17962](element-hq/synapse#17962))
- Bump pyo3 and dependencies to v0.23.2. ([\#17966](element-hq/synapse#17966))
- Update setuptools-rust and fix building abi3 wheels in latest version. ([\#17969](element-hq/synapse#17969))
- Consolidate SSO redirects through `/_matrix/client/v3/login/sso/redirect(/{idpId})`. ([\#17972](element-hq/synapse#17972))
- Fix Docker and Complement config to be able to use `public_baseurl`. ([\#17986](element-hq/synapse#17986))
- Fix building wheels for MacOS which was temporarily disabled in Synapse 1.120.2. ([\#17993](element-hq/synapse#17993))
- Fix release process to not create duplicate releases. ([\#17970](element-hq/synapse#17970), [\#17995](element-hq/synapse#17995))

* Bump bytes from 1.8.0 to 1.9.0. ([\#17982](element-hq/synapse#17982))
* Bump pysaml2 from 7.3.1 to 7.5.0. ([\#17978](element-hq/synapse#17978))
* Bump serde_json from 1.0.132 to 1.0.133. ([\#17939](element-hq/synapse#17939))
* Bump tomli from 2.0.2 to 2.1.0. ([\#17959](element-hq/synapse#17959))
* Bump tomli from 2.1.0 to 2.2.1. ([\#17979](element-hq/synapse#17979))
* Bump tornado from 6.4.1 to 6.4.2. ([\#17955](element-hq/synapse#17955))
@jmartinesp
Copy link
Copy Markdown

I may have missed some discussion in the PR, but when the MSC says 'we add a new boolean field to the request called disable_badge_count', should that field be added to the root object, like this?

{
  "pushkey": "-",
  "app_id": "foo.bar",
  "kind": "http",
  "data": {
    "url": "https://matrix.org/_matrix/push/v1/notify",
    "format": "event_id_only",
    "default_payload": {
      "cs": "-"
    }
  },
  "app_display_name": "MyApp",
  "device_display_name": "MyDevice",
  "profile_tag": "mobile_",
  "lang": "en",
  // Here
  "org.matrix.msc4076.disable_badge_count": true
}

Or is it supposed to be inside the data payload, like this?

{
  "pushkey": "-",
  "app_id": "foo.bar",
  "kind": "http",
  "data": {
    "url": "https://matrix.org/_matrix/push/v1/notify",
    "format": "event_id_only",
    // Here
    "org.matrix.msc4076.disable_badge_count": true,
    "default_payload": {
      "cs": "-"
    }
  },
  "app_display_name": "MyApp",
  "device_display_name": "MyDevice",
  "profile_tag": "mobile_",
  "lang": "en"
}


## Solution

When a pusher is registered for a given device via `POST /_matrix/client/v3/pushers/set`, we add a new boolean field
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please link to the existing spec, to help readers who don't have this context at their fingertips:

Suggested change
When a pusher is registered for a given device via `POST /_matrix/client/v3/pushers/set`, we add a new boolean field
When a pusher is registered for a given device via [`POST /_matrix/client/v3/pushers/set`](https://spec.matrix.org/v1.16/client-server-api/#post_matrixclientv3pushersset), we add a new boolean field

Comment on lines +48 to +49
When a pusher is registered for a given device via `POST /_matrix/client/v3/pushers/set`, we add a new boolean field
to the request called `disable_badge_count` which defaults to `false` if absent.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As noted by @jmartinesp here, this is unclear: is disable_badge_count meant to be at the top level or under data?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The question is really: does this only affect the http push kind, or would it also affect other push kinds (specifically, email).

It looks like it would be somewhat specific to the http kind. It also feels somewhat analagous to format (see https://spec.matrix.org/v1.16/client-server-api/#post_matrixclientv3pushersset_request_pusherdata) (and, for that matter, uri), and so should be in data.

[Honestly though, this API is horrible, in that data conflates "parameters to the homeserver" (uri) and "opaque data to pass through to the push gateway" (default_payload, for example).]

@richvdh
Copy link
Copy Markdown
Member

richvdh commented Oct 6, 2025

I may have missed some discussion in the PR, but when the MSC says 'we add a new boolean field to the request called disable_badge_count', should that field be added to the root object, like this?

I opened a thread about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client-server Client-Server API kind:maintenance MSC which clarifies/updates existing spec proposal A matrix spec change proposal push

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants