Feat: Add push provider for webpush
This pull request adds webpush support to the ntf server.
The implementation requires a VAPID key (RFC8292) to add an authentication layer to webpush. And because FCM accepts webpush requests authenticated with VAPID, it allows the feature to be used for Android with the Play Services (cf. PR on simplex-chat).
Web push requests are encrypted following RFC8291.
For this, it:
- threat ntf servers as other user servers: so the user is able to self-host the ntf server, which is best coupled with a self-hosted push service
- moves some provider agnostic functions that were in APNS module to a higher module
- add WPEndpoint and PPWebPush
- adds ntf column
- adds extras to URL of protocol servers (for the query component of the URL). This extras , is only used to get the VAPID key fingerprint from the ntf server URL yet. So Extras isn't smpEncoded yet, to avoid breaking communication with other servers. It may be used to add other fields in the future, that will need to be smpEncoded
- I've also added function to verify and delete saved connection, which is used in the other client PR
- because push endpoints may not support HTTP/2 (as per RFC8030), it currently rely on http-client module and doesn't keep any connection (cf. possible improvements)
- the VAPID header is cached for one hour, to avoid recalculating it and checking the signature for every messages, as recommended per RFC8292
This PR is already long enough, but as a 2nd step, this can be improved by:
- Adding a new NtfMode (PING), to send maximum a push message per second. It can reduce a lot the number of push messages and reduce some advanced analytic attacks with compromised push server. Having a push message per new message is not necessary, the client will sync for a few seconds when a push message arrives.
- Caching (some) connection to push servers, as it is done with APNS. This need is reduces if the PING notif mode is implemented, but it may be useful if a single push server is heavily used (and support http2)
- Restrict IPs that are authorized to be requested by ntf server with web push (for example, to avoid registering http://localhost as a push server), risks are limited since the content of push notifications sent from ntf server aren't arbitrary. Until then, it is possible to restrict them using systemd service, by setting the property
IPAddressDeny=":: ::1 ::ffff:0:0/96 2001:2::/48 2001:db8::/32 3fff::/20 fc00::/7 fe80::/10 0.0.0.0 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 192.0.2.0/24 198.51.100.0/24 203.0.113.0/24 198.18.0.0/15 240.0.0.0/4 255.255.255.255"
PS: There might be non-idiomic syntaxes, this is the first time I do things in haskell PPS: If you want/need, you can contact me on SX, I'll share a contact address :+1:
@p1gp1g let's connect please - my address is here, or you can ask support to connect me (Ask SimpleX team), or send yours.
Thank you.
I've split in 3 PR at this moment:
#1611 #1612 #1613
TODO:
- Allow user-defined ntf servers
- Add functions to verify saved ntf token, with unencrypted code (7fd0e27e2fac5479870994cc0bbf3c5d03c23c2b) and to delete saved ntf token (f5720a254104d70b33ac1479ffa9d24ba9988b59) => Do you think you can provide them ? They were using the user-defined ntf servers
- Add VAPID (need something to replace Extras)