on main help sign in
git clone ssh://git.iko.soy/deskjam
deskjam

deskjam

How this fork differs

This is a fork of tinnus-napbus/deskjam. It adds support for installing and updating apps by uploading .deskjam files.

Apart from the security fixes below, everything upstream deskjam does still works the same way, and stays the default:

New, and opt-in:

New, and always on:

It also fixes these security problems. These fixes are always on:

If you reach your ship over plain http through a reverse proxy that changes the Host header, the proxy has to tell your ship the address the browser used. Otherwise deskjam refuses its own forms, with a message that says so. Passing on the browser's Host works (in nginx, proxy_set_header Host $http_host;), and so does an X-Forwarded-Host header, which Apache adds by default, or Forwarded: host="...".

The tile icon is part of the docket, url-encoded, where upstream's comes from a web server. deskjam only reaches outside your ship when you upload from a url.

See Installing and updating apps for details, and Replacing upstream deskjam to switch to this fork.

Building

You can build the full %deskjam desk with the mortar build tool available here. It writes the desk to dist.

Or, with Nix with flakes enabled, run nix build, which writes the same desk to result. flake.nix pins the same dependencies as mortar.yaml, so change them together. Nix only sees files git knows about, so after adding a file to desk, run git add (or any jj command, such as jj status) before nix build.

The app's tile icon, assets/deskjam.svg, is a copy of upstream's. desk/desk.docket-0 carries it url-encoded, as a data: URL, so Landscape shows it without loading anything, including in previews on other ships before they install deskjam. After changing the icon, replace the URL in the docket's image with the output of this, run in the repo: python3 -c 'import urllib.parse as u; print("data:image/svg+xml," + u.quote(open("assets/deskjam.svg").read(), safe=""))'. nix build checks that the two match.

Testing

nix flake check builds the desk, checks that mortar.yaml pins the same files at the same revisions as flake.nix, and runs the Hoon tests in tests/hoon with urbit eval. Those cover the url handling, the cross-site check and the upload guards, and need no ship. To run just them: nix shell --inputs-from . nixpkgs#urbit -c tests/hoon/run.sh.

tests/fakezod boots a fake ship, installs your working copy of deskjam on it, and drives its web interface with curl. Its smoke-test.sh uploads, installs and replaces a test app. See its README.

CI runs nix flake check on every push, and the fake-ship test on pull requests.

Installation

~donmec-sallud publishes this fork. To install it, run |install ~donmec-sallud %deskjam in the dojo. Your ship then gets deskjam's updates from that ship. shelf.iko.soy lists all the apps ~donmec-sallud offers.

To install it from this repo instead:

  1. Clone this repo: git clone https://github.com/iko-soy/deskjam.
  2. Boot up a ship (fakezod or moon or whatever you use).
  3. |new-desk %deskjam to create a new desk called %deskjam.
  4. |mount %deskjam to access the %deskjam desk from the unix command line.
  5. At the unix command line rm -rf [ship-name]/deskjam/* to empty out the contents of the desk.
  6. In the repo, run mortar build, or nix build.
  7. Copy the contents of dist to [ship-name]/deskjam. After nix build, copy result instead, and make the copies writable, since files Nix builds are read-only. From the repo: cp -R result/. /path/to/[ship-name]/deskjam/ && chmod -R u+w /path/to/[ship-name]/deskjam.
  8. At the dojo command line |commit %deskjam.
  9. Install with |install our %deskjam.

Replacing upstream deskjam

If your ship already runs upstream deskjam, you can install this fork through it, without access to the ship's files:

  1. Get this fork as a deskjam: in a clone of this repo, run nix build, then tests/fakezod/pack.sh result deskjam deskjam.deskjam, as Deploying an app says. Or download the %deskjam desk from [your-domain-name]/apps/deskjam on a ship that runs this fork.
  2. On your ship, run +vats %deskjam in the dojo. If its source ship isn't ~, kiln keeps it in sync with the ship you installed it from, and that ship's next release would replace the fork. Run |pause %deskjam first.
  3. Upload the deskjam on [your-domain-name]/apps/deskjam. On the next page, under Stage a desk to merge with, choose deskjam: the list starts on whichever desk comes first, not on %deskjam. Submit, check that the confirm page names %deskjam, then confirm.

This drops any upload you had staged but not yet committed. To install a later version of this fork, upload it the same way and choose Replace.

Kernel updates

This section is for a deskjam you installed from this repo or uploaded: one installed from ~donmec-sallud gets new versions from that ship instead.

When Urbit releases a new kernel, your ship suspends every desk whose sys.kelvin doesn't list it, and a suspended deskjam can't upload its own update. So before your ship takes a new kernel, install a version of this fork that lists it: get it as a deskjam, as in step 1 above, then upload it with deskjam and choose Replace. It still lists your current kernel too, so Clay applies it right away, and deskjam keeps running through the upgrade.

If your ship has already upgraded, |revive %deskjam won't work. Install the new version as in Installation, steps 4 to 8, and Clay starts deskjam again.

Usage

  1. To download a desk as a deskjam, go to [your-domain-name]/apps/deskjam, choose the desk under download deskjam, and click download.
  2. To download some of a desk's files, check subset first, then choose the files.
  3. To see a desk's status, choose it there and click status.
  4. To install or update an app, or upload a jammed desk, go to [your-domain-name]/apps/deskjam and follow the instructions there. See Installing and updating apps.

Installing and updating apps

Only upload deskjams from people you trust: an app's agents run as your ship, and can read and change anything on it.

Deploying an app walks through the simplest way to put an app on your ship, deskjam itself included: pack its desk with tests/fakezod/pack.sh, then upload it here.

Upload a deskjam on [your-domain-name]/apps/deskjam, from a file or a url. The next page describes the upload (its app, kernel version and agents) and asks where it should go:

Every upload is a single Clay commit. When the desk is running, Clay rebuilds its agents as part of that commit and reloads those whose code changed. If a file or agent fails to build, or a running agent fails to load its state, Clay rejects the whole commit. The desk stays as it was, the browser shows an error, and your ship's dojo shows why. (An agent that is new to the desk and crashes as it starts doesn't stop the commit.)

Before you confirm, deskjam lists the files it will delete, add and change, the files that stay the same, and for a merge the files it leaves in place. Files it can't compare, because it doesn't know how their mark stores them, are listed as files that may change. Files that stay the same are left out of the commit. It also checks the upload. Apart from /sys/kelvin files it can't read, it only refuses what Clay would reject or ignore anyway:

deskjam finds what a mark or agent needs by reading the imports at the top of each file, as Clay does. It doesn't compile anything, so a file with a type error still only shows up when Clay refuses the commit.

It also refuses two things only the new replace option could do: replacing %base or %kids, or dropping a desk's /desk/bill and so stopping all its agents. Everything else is a warning:

The confirm page only commits what it showed you. If the upload, its destination or the desk changed since, in another tab or by a commit or a kiln update, it asks you to check again.

After the commit deskjam shows the desk's status. That covers its revision, whether it is running, its agents, the kernel it is for, its glob, whether kiln syncs it, and whether the upload made a new revision. If the upload matched what the desk already had, or Clay is holding it for a newer kernel, there is no new revision. If the desk should have started but didn't, the status page says so, and if it was left suspended, how to start it.

Url uploads follow redirects and send escapes like %20 as written (the runtime on its own would decode them), so links to GitHub release assets work. Link to the file itself, not to a page about it. A fetch gives up after 10 minutes, and stops when you go back to the start page. If it fails, the staged page says why. Urls on your ship's machine or local network are refused unless you tick allow local addresses.

Apps with globs

An app's web frontend, its glob, isn't part of its desk: Landscape's %docket agent fetches it as the desk's docket says. For an app that serves its glob from your ship, the confirm page can set the glob's hash in the docket, so the app's repo doesn't need it. Apps with globs has the whole procedure.

If an update goes wrong

Before confirming an update, the confirm page offers a download of the desk as it is now. Keep it: uploading it again and choosing Replace puts the desk back. That doesn't work for %base and %kids, which deskjam won't replace.

Putting an older version back usually fails safely when the update changed the state an agent keeps: the old agent can't load the new state, so Clay refuses the commit, and nothing changes. But an agent that starts afresh from state it can't read, as deskjam itself does, loses that state instead. If the update changed the hash of a glob your ship serves, also upload the old frontend at /docket/upload.