BlueBubblesApp / bluebubbles-server

Server for forwarding iMessages to clients within the BlueBubbles App ecosystem
https://bluebubbles.app
Apache License 2.0
554 stars 47 forks source link

Remote config service #586

Open kerfouffle opened 1 year ago

kerfouffle commented 1 year ago

Overview

This patch adds what I'm calling a "remote config service". That is: a service that listens on a Unix Domain Socket that gives users the ability to change config values on the fly. This is very similar to the functionality already provided by the code in packages/server/src/main.ts that reads from stdin, but with the added benefit of not needing to have to relaunch via terminal. Additionally, the service can be accessed "remotely" (hence the name), for example from an SSH session where the user does not have access to the Terminal window running BlueBubbles.

Rationale

I noticed a few people in the Discord request a feature like this. It is of course already possible to change config values from the GUI, but if the user does not have direct physical access to the Mac, their only option is a remote-desktop solution like VNC. Remote desktop is a pretty heavy-weight solution, given that it has to mirror an entire display over the Internet, and many home networks may not have great speeds. SSH, by comparison, is much more light-weight since it is text based. Additionally, the VNC protocol offered by macOS is not encrypted by default, whereas SSH is. It is also easier to interact with a text-based command prompt than a remote desktop UI on a phone, for users for whom that is their primary or only device.

Technical details

The service starts up like all other services defined in packages/server/src/server/services/index.ts, and managed by the BlueBubblesServer class. It listens on a Unix Domain Socket which is created in the userData directory: ~/Library/Application Support/bluebubbles-server/remote-config.sock. When a client connects, it first presents a welcome banner and some explanatory text, then starts reading from the socket in the same way it would read from stdin: utf-8 text lines delimited by '\n'. From there, the functionality is nearly identical to the existing stdin functionality; it has all the same commands.

Usage

The way an end-user would interact with this feature is as follows:

Screenshot:

image

Design

I specifically wanted a solution that didn't require the user to install an additional command line utility. Requiring that would add a lot of complexity: where would it live? how would it receive updates? How would it get installed in the first place? Are we sure it's on $PATH? If not, how can we instruct the user to add it to $PATH? And and make sure it's persistent for whatever shell they're using (zsh has .zshrc, but bash has .bashrc or .bash_profile depending on how it feels that day). This is further complicated by the fact that the user-base for this app is not necessarily highly technical, and I didn't want to add more support requests to the Discord.

This led me to the nc solution. Netcat is standard on many unix platforms, and that includes macOS. The main downside is that the user needs to type in the full path to the unix socket (~/Library/Application ugh I'm so sick of typing that). This can probably be easily copy and pasted from documentation or a tutorial, but it is still not ideal. Perhaps you may want to switch the path to something simple like ~/.bluebubbles.sock, which is easier to remember and type.

Closing thoughts

Feel free to re-write this PR however you see fit. Rename the feature to whatever you want, I just kinda picked it because it made sense to me at the time.

Also, I duplicated a bunch of code from packages/server/src/main.ts that might need to be extracted out into its own file or class.

Also also: the lineExtractor.ts file probably fits better in helpers/utils

cameronaaron commented 5 months ago

Id be interested in this for some reason my team viewer is down and I cant access my machine in a different state

zlshames commented 4 months ago

@kerfouffle i know it's been a while, but i do plan on fixing the issues and merging it. It'll likely go as part of 1.9.9 (not the next release)