Open kerfouffle opened 1 year ago
Id be interested in this for some reason my team viewer is down and I cant access my machine in a different state
@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)
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 fromstdin
, 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 theBlueBubblesServer
class. It listens on a Unix Domain Socket which is created in theuserData
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 fromstdin
: utf-8 text lines delimited by'\n'
. From there, the functionality is nearly identical to the existingstdin
functionality; it has all the same commands.Usage
The way an end-user would interact with this feature is as follows:
Terminal.app
, an SSH session, etc.nc -U ~/Library/Application\ Support/bluebubbles-server/remote-config.sock
(thenc
command is built-in to macOS).Welcome to the BlueBubbles configurator!
and a call to action for thehelp
andexit
commands.stdin
:show
,set
, andrestart
.exit
to exit (or Ctrl-C to violently kill thenc
process if the connection is misbehaving for whatever reason).Screenshot:
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 inhelpers/utils