Introduce user & global archiving controls; add unregister function
- WARNING to operators: You MUST run fixup_2.sql in order to use this and newer
versions of the bridge.
- Archiving and full chat history fetches are now a configuration setting (and
default to off).
- Users now have to enable archiving manually by talking to the admin user, and
are warned about the potential privacy implications.
- Users can now completely remove themselves from the bridge, deleting all data.
- Bridge administrators can now be specified by adding an entry to the
'administrators' SQL table with your JID. These can force-unregister specific
users.
@ -23,20 +23,21 @@ additional caveats: take a look at the requirements list.
@@ -23,20 +23,21 @@ additional caveats: take a look at the requirements list.
## What works?
- Sending private messages/DMs both ways
- *Basic* support for MUCs
- Support for MUCs
- Magically populating your roster using [XEP-0144: Roster Item Exchange](https://xmpp.org/extensions/xep-0144.html)
- Downloading/decrypting media from WhatsApp and uploading it to your XEP-0363 server
- Avatars
- Read receipts
- Status text
- Typing notifications / chat state
- [XEP-0313: Message Archive Management](https://xmpp.org/extensions/xep-0313.html) in MUCs *only when enabled in configuration*
- Fetching your entire message history from WhatsApp and making it available via MAM *only when enabled in configuration*
- Users joining and leaving MUCs, and the topic changing (partial, requires XMPP-side rejoin)
- Uploading images to WhatsApp natively
## What doesn't yet?
- [XEP-0313: Message Archive Management](https://xmpp.org/extensions/xep-0313.html) in MUCs (DMs should be done by your server)
- Support for users joining and leaving MUCs
- Support for the topic changing in MUCs
- Uploading media to WhatsApp (currently, it just comes through as a link)
- Uploading non-image media to WhatsApp (currently, it just comes through as a link)
- Probably other stuff
## What you'll need
@ -96,6 +97,27 @@ A few things to note here:
@@ -96,6 +97,27 @@ A few things to note here:
- The `shared_secret` is the same as the `component_secret`.
- The `upload_component_name` is the name of the XEP-0363 HTTP Upload component.
#### Enabling archiving and full history fetches
If you want to be able to use the MAM and full history fetch features, you'll need to run some additional commands in the above `sqlite3` window.
To let users use MAM:
```
sqlite> UPDATE configuration SET allow_archiving = true;
```
To let users fetch their WhatsApp history:
```
sqlite> UPDATE configuration SET allow_history_fetches = true;
```
**WARNING:** These options are NOT recommended for people wishing to run a public instance of the bridge. (In fact, if you're doing that, come talk to us in the support MUC first, as there are various things you probably want to be made aware of.)
Note that users must still enable archiving manually via talking to the admin user and executing the `enable-archiving` command (and similarly for history fetches, which use the `full-history-fetch` command).
### Step 3: run the bridge
You can build the Docker image yourself from the `Dockerfile` in the repo, or you can just
@ -377,7 +390,7 @@ WhatsXMPP represents users as u440123456789 and groups as g1234-5678."
@@ -377,7 +390,7 @@ WhatsXMPP represents users as u440123456789 and groups as g1234-5678."
@ -658,14 +671,15 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
@@ -658,14 +671,15 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
@ -872,6 +886,18 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
@@ -872,6 +886,18 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
(admin-msgcompjid"(will retry)")
(setfstored-connnil)))))))))
(defununregister-user(compuid)
"Unregister the user with id UID from the bridge."
(admin-msgcompuser-jid"You have been unregistered from the bridge, and all data has been deleted. Have a nice day!"))))
(defunstart-user-registration(compjid)
"Register the JID as wanting to use the bridge COMP."
(with-component-data-lock(comp)
@ -941,10 +967,31 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
@@ -941,10 +967,31 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
(and(notuid)(equalbody"register"))
(anduid(equalbody"register -force")))
(start-user-registrationcompstripped))
((equalbody"unregister")
(reply"Are you sure? Unregistering will delete ALL information the bridge has about you, and is not reversible. If you still want to continue, execute the `unregister -force` command."))
((equalbody"unregister -force")
(ifuid
(unregister-usercompuid)
(reply"You're not registered with the bridge.")))
((equalbody"help")
(reply*admin-help-text*))
(progn
(reply*admin-help-text*)
(when(jid-admin-pstripped)
(reply*admin-privileged-help-text*))))
((notuid)
(reply"You're not registered with this bridge. Try `register` or `help`."))
((equalbody"enable-archiving")
(reply"Are you sure you want to enable archiving? Doing this will store your WhatsApp messages, *unencrypted*, on the server of the bridge operator, where they can be easily read! If you still want to continue, execute the `enable-archiving -force` command."))
((equalbody"enable-archiving -force")
(if*archiving-enabled*
(progn
(user-set-archiving-stateuidt)
(reply"Archiving enabled."))
(reply"Archiving cannot be enabled on this bridge. Please contact the bridge administrator.")))
((equalbody"disable-archiving")
(progn
(user-set-archiving-stateuidnil)
(reply"Archiving disabled. WARNING: Message history is not cleared. To do that, unregister from the bridge entirely (deleting all data), and re-register.")))
((equalbody"getroster")
(progn
(do-roster-exchangecompstrippeduid)
@ -960,21 +1007,23 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
@@ -960,21 +1007,23 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
(reply(formatnil"Fetching full chat history for ~A groupchats. This will probably take a long time.~%Note that even after completion is reported, some background media uploading may be in progress.~%If the WhatsApp connection is interrupted midway through the fetch, you will need to retry the fetch."
(reply(formatnil"Fetching full chat history for ~A groupchats. This will probably take a long time.~%Note that even after completion is reported, some background media uploading may be in progress.~%If the WhatsApp connection is interrupted midway through the fetch, you will need to retry the fetch."
@ -993,6 +1042,16 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
@@ -993,6 +1042,16 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
(reply(formatnil"Refreshing metadata for ~A..."localpart-to-use))
(reply"Unknown command. Try `help` for a list of supported commands."))))))
@ -1363,13 +1422,19 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
@@ -1363,13 +1422,19 @@ Returns three values: avatar data (as two values), and a generalized boolean spe
"Initialise the whatsxmpp bridge."
(connect-database)
(with-prepared-statement
(config"SELECT server, port, component_name, shared_secret, upload_component_name FROM configuration WHERE rev = 1")
(config"SELECT server, port, component_name, shared_secret, upload_component_name, allow_archiving, allow_history_fetches FROM configuration WHERE rev = 1")
(assert(sqlite:step-statementconfig)()"No configuration in database!")
(format*debug-io*"~&[!] WARNING: Archiving of user messages is enabled. If you're running a public bridge, this has potential privacy implications!~%"))
(format*debug-io*"~&[!] WARNING: Full history fetches are enabled. Letting any user initiate a full history fetch is a potential Denial of Service vector!~%"))