Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tracking issue] Webxdc notifications #6097

Closed
Hocuri opened this issue Oct 23, 2024 · 6 comments
Closed

[Tracking issue] Webxdc notifications #6097

Hocuri opened this issue Oct 23, 2024 · 6 comments

Comments

@Hocuri
Copy link
Collaborator

Hocuri commented Oct 23, 2024

Summary

Webxdc apps should be able to show notifications. E.g. a chess app should be able to show a notification "Hocuri made a move" to my opponent. In a group, the chess app should be able to show the notification only to my opponent and not to everyone else.

In order to do this, when I make a move, the chess app can call sendUpdate(payload: { ..., notifyUsers=[𝘰𝘱𝘱𝘰𝘯𝘦𝘯𝘵'𝘴 𝘶𝘴𝘦𝘳 𝘪𝘥] }, ...).

Webxdc API design

New APIs:

  • A new API selfID or reuse the existing API selfAddr. Returns a unique identifier that can be used to address the current user. How it looks is up to the host implementation; in Delta Chat, it will be the public key fingerprint for the time being. Note: with multi-transport, this can't be the email address anymore, since email addresses will change from time to time.
    • The initial implementation should probably just start with reusing selfAddr
    • If we add a new API selfID, selfAddr will need to become an alias for selfID sooner or later because there won't be stable email addresses anymore. So, I think we should just go for reusing selfAddr.
  • A new field senderID/senderAddr on incoming status updates.
    • Alternatively, we could require the apps to always send the selfAddr within the payload themselves.
      • Pro this alternative: Changing what selfAddr is (e.g. making it a hash of the key and the app id) isn't a breaking change anymore
      • Contra this alternative: This would make our design incompatible to an XMPP bridge (see "Complications" below).
      • Contra this alternative: If we ever want to introduce "whispering", the host implementation will also need to know which webxdc addr corresponds to which contact.
      • Contra this alternative: Having a senderID field on incoming status updates is valuable on its own
  • The payload of sendUpdate() takes a new field notifyUsers, a list of user ids/addresses. The receiving side will then send a notification if the own user id is in the list.
  • The payload of sendUpdate() takes a new field notificationText that is shown in the notification on the receiving device; Alternative: reuse the existing field info (info is shown on the system messages that are posted in the chat already for every status update)
    • The initial implementation should probably just start with reusing info, adding notification_text will be easy later

Complications

  • Bridges to XMPP/Cheogram: As far as we know, the current design can be compatible with an XMPP bridge, but the bridge will have to swap the senderAddr from DC's fingerprint with the XMPP user identifier.
  • Translations: With the current design, the notificationText can't be translated, or if it is, it will use the language of the sender, not the receiver. This is a problem with info already, too, and there are also previous thoughts on how this might be fixed in the future.
    • Solution 1: allow to specify a dictionary translatedNotificationText instead of notificationText that maps from the country code to the respective translation.
    • Solution 2: translatedNotificationText contains a label and parameters, e.g. label="opponent_made_points",parameters=["3"]. Then, the receiving device will look up the the translation corresponding to the label in a file with a well-known name (e.g. /translations.xml), in our example that will be "Your opponent made %1$s points", and the parameters are substituted so that we get "Your opponent made 3 points".

Implementation in DC between core & UIs

  • Core will need a new API get_webxdc_self_addr() or a new config webxdc_self_addr that returns the fingerprint or whatever we will use as the identifier in the future.
  • Core can simply add a new field senderAddr to the payload of incoming status updates.
  • Core can simply accept a new field notifyUsers in the payload of incoming status updates, and check if it contains the self addr and whether the user ever sent out a status update for this webxdc (we don't want to allow sending notifications if the user never opened the app). Then, there are multiple ways to actually send the notifications:
    • Solution 1: Send an IncomingMsg event instead of MsgsChanged for the system message.
      • However, this is the first time that core is emitting IncomingMsg for system messages, therefore UIs will need to be adapted.
      • Also, right now, the system messages get updated when multiple updates arrive in a row, not sure how well the UIs handle this.
      • And finally, not every webxdc update creates a system message. While I can't think of a case where we would want to show notifications but no system message, this may be a limitation.
    • Solution 2: Save the webxdc update messages into a special chat (id=8 or so) instead of the TRASH chat, and declare that this special chat is dedicated to showing notifications that don't belong to any Message shown to the user, and send an IncomingMsg event for this message.
      • This solution is probably more effort, but also more flexible.
    • In any case, the UIs will need to add support for directly opening the webxdc when clicking on the notification, or just scrolling to it and highlighting it.
      • Pro directly opening: Smoother user experience (one click less)
      • Contra directly opening: It may be unexpected for users.
      • Contra directly opening: Might be used by attackers to trick the user into opening a malicious webxdc
        • Malicious webxdc = Phishing form or a webxdc that escapes the WebView sandbox via an exploit (not all webviews are updated, esp. on Android)
        • Mitigation: don't allow sending notifications if the user never opened the app. Alternatively, only directly open it if the chat is not a contact request.
  • Core can mostly decide on its own which text is shown in notifications (and it doesn't have to be the same text that is shown in the message)
  • Core can access the webxdc's files itself (this might be necessary to read translations from it).

Alternatives

  • For the user id/addr, instead of the public key fingerprint, use a hash of the fingerprint together with the webxdc message's Message-Id.
    • Pro: Privacy
    • Contra: Complexity
    • Contra: All chat partners know the public key fingerprint anyway, and the webxdc (hopefully!) isn't able to send the fingerprint anywhere else.

Future possibilities

  • Deep linking, i.e. opening a specific screen in the Webxdc app when it is opened via a notification
    • mostly UI and specification work, and probably an additional field on info messages and notifications for the deep link in core.
  • Adding access to avatars for webxdc's will be easy as soon as we have these unique ids (virtual directory /avatars/:id.jpg) (@Simon-Laux: "sounds like fun, if I have time then, then I volunteer to add it").
@Hocuri Hocuri added the webxdc label Oct 23, 2024
@Simon-Laux
Copy link
Contributor

Simon-Laux commented Oct 23, 2024

in Delta Chat, it will be the public key fingerprint for the time being. Note: with multi-transport, this can't be the email address anymore, since email addresses will change from time to time.

There were also privacy concerns, not only technical concerns about multi-email.
I think could be solved by hashing keyfingerprint together with webxdc message's rfc-message-id.

On a related note adding access to avatars for webxdc's will be easy as soon as we have these unique id's. (virtual directory /avatars/:id.jpg) but that's just sth if we have enough time left (sounds like fun, if I have time then, then I volunteer to add it).

Contra directly opening: Might be used by attackers to trick the user into opening a malicious webxdc

malicious webxdc -> should not be possible to create. But we could say if chat is not contact request, then directly open it. The only attack without exploits that I can imagine right now is a spammer sending a phishing form.

Deep linking, i.e. opening a specific screen in the Webxdc app when it is opened via a notification

mostly UI and specification work, and probably an additional field on info messages and notifications for the deep link in core.

Core can access the webxdc's files itself

core already reads the manifest from the webxdc archive.

@Septias
Copy link
Collaborator

Septias commented Oct 24, 2024

We could also add a translations.md or something similar to webxdcs to provide the translation data. Could also be some more structured format like yaml or JSOSN. Could be nicer and remove the need for some initial protocol to communicate translations

@Simon-Laux
Copy link
Contributor

on the note of translatable webxdc info messages: https://support.delta.chat/t/localised-info-messages/2728

But I think that's still out of scope for now.

@Hocuri
Copy link
Collaborator Author

Hocuri commented Oct 25, 2024

I edited my original post with the most important points, and included my own thoughts:

  • Contra directly opening: Might be used by attackers to trick the user into opening a malicious webxdc
    • Malicious webxdc = Phishing form or a webxdc that escapes the WebView sandbox via an exploit (not all webviews are updated, esp. on Android)
    • Mitigation: don't allow sending notifications if the user never opened the app. Alternatively, only directly open it if the chat is not a contact request.

Alternatives

  • For the user id/addr, instead of the public key fingerprint, use a hash of the fingerprint together with the webxdc message's Message-Id.
    • Pro: Privacy
    • Contra: Complexity
    • Contra: All chat partners know the public key fingerprint anyway, and the webxdc (hopefully!) isn't able to send the fingerprint anywhere else.

Future possibilities

  • Deep linking, i.e. opening a specific screen in the Webxdc app when it is opened via a notification
    • mostly UI and specification work, and probably an additional field on info messages and notifications for the deep link in core.
  • Adding access to avatars for webxdc's will be easy as soon as we have these unique ids (virtual directory /avatars/:id

@r10s
Copy link
Contributor

r10s commented Nov 17, 2024

thanks for discussions and thoughs, i created new issues from that and from the things currently have priority; the issues directly referring here are linked above. all issues at a glance are in the project https://github.com/orgs/deltachat/projects/77/views/1 now

closing this issue, discussion of course can continue here

@r10s r10s closed this as not planned Won't fix, can't repro, duplicate, stale Nov 17, 2024
@r10s
Copy link
Contributor

r10s commented Nov 17, 2024

for translations:

an alternative is to let the sender send all supported translations in the payload:

  • that would make the effort on both sides, messenger-implementors and .xdc-devs, easier - esp. the latter can use their favourite tool throughout the app and do not need to deal with sth. additional. also, that would remove the "plurals" and whatnot forms from our responsibility (would be needed for "Solution 2")

  • downside is that the payload is larger, as several translations are send - but it is questionable if that matters in practise

also for practise: translations are out of scope of adding notifications wrt M2/M3 proposal. as mentioned above, notifications do not add much to the existing issue. also, there are rarely any apps that support translations at all, so, there are more interesting fields to target to make webxdc more a thing

side note for casual readers: translations are possible in general already today. the discussion is only about the case the sender and the receiver use different languages. a true issue. however in many cases receiver and sender, as being in the same chat, have some common languages, so that could also be solved socially. also this issue does not pop up often, as, as said vast majority of apps are english - without webxdc api reasons :)

r10s added a commit that referenced this issue Nov 22, 2024
this PR adds support for the property `update.notify` to notify about
changes in `update.info` or `update.summary`. the property can be set to
an array of addresses [^1]

core emits then the event `IncomingWebxdcNotify`, resulting in all UIs
to display a system notification, maybe even via PUSH.

for using the existing `update.info` and `update.summary`: the message
is no secret and should be visible to all group members as usual, to not
break the UX of having same group messages on all devices of all users -
as known already from the normal messages.

also, that way, there is no question what happens if user have disabled
notifications as the change is presented in the chat as well

doc counterpart at webxdc/website#90

closes #6217 

[^1]: addresses come in either via the payload as currently or as an
explicit sender in the future - this does not affect this PR. same for
translations, see discussions at #6217 and #6097

---------

Co-authored-by: adb <[email protected]>
Co-authored-by: l <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants