A person with several sia.storage accounts (or phrases) could not tell
which one a Pithos s3d used: s3d records only the indexer URL. Pithos now
reads the app key s3d stores after login and asks the indexer, with a
request signed the way indexd's app API expects, for the account's key,
storage used and last use. Those match what sia.storage shows for the app,
and the page explains that the login and the phrase together decide the
account. Earlier accounts set aside on this computer show their key too.
The music player had no volume control; it now has a slider beside a
mute button (a pop-up slider on narrow screens), remembered between
visits.
The share dialog asked for a "public address of s3d" before making a
link, which nobody could fill in usefully. The link is now made as the
dialog opens, with a plain note that it opens only on this computer
while s3d listens on 127.0.0.1; your own public address moved under
"Use my own public address". The Access dialog says the same about
what public means while s3d is local, and that access can be changed
at any time. Dialogs now draw above the player.
A server-sent file list could name paths outside the s3d folder (or the key
file in it), and a failed move back deleted every listed path. Transfers now
accept only s3d data paths, check all of them before writing, never
overwrite, and clean up only what they wrote.
A lost reply could lose or fork the drives: move-up and move-down now ask the
server who holds them before touching the local copy, and once the server is
told to release, the local copy is never removed (the release is retried).
The gateway no longer lets one account route another's access key id, refuses
. and .. in shared-key paths, strips presign parameters before re-signing,
counts upload size on disk, stops s3d before it can be restarted mid-move, and
claims sign-up proofs before checking them. The key file is never replaced
when unreadable, a local edit removes the older encrypted copy, listing pages
no longer repeat, and data hashes stream instead of loading whole files.
In the sidebar the menu now drops down from a ☰ in the top-right
corner, opposite the Pithos name, and holds every page plus Open as
full page, instead of pushing the page down.
Get started and Sia connection become one Account page: the guide
until an account is connected, then the account with its label, Add
another account (the guide, titled Add a Sia account) and the other
accounts on this computer, each one click to switch back to.
On narrow screens file rows show Download and Share as icons, hide
the size, and wrap names to two lines at most.
Pithos only updated when Theseus happened to check the extension
channel on a restart, and nothing showed which version was running.
A footer now shows pithos.sia and the version, as Aegis's does. In
Theseus it checks the channel when Pithos opens and every six hours;
a newer release shows as "↑ vX", one click downloads and verifies it,
and a second asks Theseus to restart and apply it. ↻ checks on demand.
Opening an MP3 used to show it in a dialog, so the music stopped as soon
as you went on looking through your drive. Audio now plays in a player
docked at the bottom of Pithos that stays through folder, drive and page
changes and plays on through the folder it started from, with previous,
next, seek and the keyboard's media keys. An expired view link is
renewed mid-track instead of stopping playback.
Drives and folders can be shown as icons (pictures preview themselves),
a compact list, or a details table with type and date, remembered per
page. Per-item actions move into a ⋯ menu so rows fit a narrow panel.
In the 400 px Theseus sidebar the navigation folds into a compact bar
with the page name, the s3d status and a menu button, so the page gets
the room. The Widen button is gone: widening squeezed the open tab and
the right sidebar. Full page opens Pithos as an ordinary tab instead.
Records what was built against the plan (names are encrypted from v1, rights
for other people are folder-scoped S3 keys), how to run pithos-hosted, and
that paid storage belongs to Hestia, a separate product.
Settings gains a sign-in, sign-up and move card for Silent Mode; Overview,
the status pill, Access and Share follow the server when drives are hosted.
Folders get their own Share (public, or a key with read/add/edit rights),
since per-folder access is what hosting adds over a bare s3d. Files the
server can still read are marked, and Access can encrypt the ones that
predate the move.
The gateway is the only thing standing between a shared key and the rest of
an owner's drive, so its SigV4 check, grant decisions and the BNS/deposit
proofs get tests that need no s3d to run.
s3d binds one Sia account per process, so the server runs one s3d per
person (pithos-hosted), started on demand and flushed and stopped when idle.
Only the connected s3d data folder moves between PC and server; the Sia
recovery phrase never leaves the PC and nothing is re-uploaded to Sia.
Because the server holds the connection key, local Pithos encrypts names and
contents before they leave the machine, with keys from the Theseus vault (or
a local key file elsewhere). What s3d cannot do on its own, the gateway now
enforces: public folders, expiring share links and S3 keys for other people
limited to one folder with read, add-only or edit rights. Files those reach
are stored readable, since visitors have no key, and go back to encrypted
when the rule is removed. Sign-up needs a BNS name signature, a deposit or
an invite, with a per-IP limit.
Hosted drives sit on a server that holds the Sia connection key, so private
files must be unreadable there. Names are encrypted per path segment with
AES-SIV (deterministic, so folders and prefix listing still work on the
server) and bodies with chunked AES-256-GCM bound to drive and path, with
sizes computable both ways so uploads stream and range reads stay cheap.
s3d only sends full ~40 MB blocks to Sia, so a handful of small files can
stay in the local buffer forever (seen: 63 objects, 6 MiB, nothing on Sia).
An opt-in setting now flushes once the pending set has not changed for N
minutes, judged from s3d's upload stats so uploads from any S3 client count.
Failed flushes back off up to an hour instead of hammering a broken indexer.
One s3d serves one Sia account, so hosting means one s3d per user on the
server. Writing down the agreed model (bring your own sia.storage account,
client-side encryption except public files, BNS-name-or-deposit gate), how
the gateway enforces per-folder rights s3d cannot, and how a data folder
moves between PC and server without re-uploading to Sia, before building.
A bucket is the top level you put folders into, so it reads better as a drive than as a folder: the menu and page say Drives, each tile is a drive icon with the files and size it holds (counted in the background, up to 20,000 files, then shown as N+), and the subtitle says S3 apps call it a bucket. Folders inside a drive stay folders. New usage endpoint: GET /api/s3/:user/buckets/:bucket/usage.
- s3d kept stopping: Pithos stopped it whenever the extension restarted
(every update, every Theseus quit) and never started it again. Start
and Stop now record what the user wants (pithos-prefs.json beside
s3d.yml); Pithos starts s3d with Theseus and when opened, and retries a
crash up to three times in ten minutes, logging why it skips. The
Buckets page also redraws when s3d starts or stops; it used to keep
saying "not running".
- One view at a time: "Full page" opens Pithos in a tab and closes the
left panel; the tab has "Back to sidebar", which reopens the panel.
- Every new user gets a bucket of their own, named after them (lowercase,
hyphens) or as typed in the New user dialog.
- Buckets show as folder tiles. New folders are kept while empty with the
usual "<name>/" marker object.
- A viewer: images, audio (mp3 and friends), video and text open inside
Pithos, with Share and Download. The Theseus panel uses 10-minute,
reusable, inline view links so players can make range requests.
- The Access dialog says what s3d cannot do: per-folder public access and
write rights for others are not supported, only whole-bucket public read.
"Acting as" read like a choice of Sia account; it picks an S3 user on
this s3d, and every user shares the one Sia account the s3d is connected
to. So:
- The picker is "S3 user", with a tooltip saying all users share one Sia
account; Buckets explains what a bucket is.
- Buckets and the Overview show "Sia account: <label> (indexer)". Pithos
cannot see the account's email, so the Sia connection page lets the
user label it (kept in pithos.json beside the s3d data).
- "Switch Sia account" stops s3d and moves its data (connection, users,
keys, buckets, upload buffer) into previous-account-<stamp>/ next to
s3d.yml, never deleting it; the guide then connects another account.
It warns about uploads still waiting for Sia and offers a flush, and
refuses while another s3d serves the config.
- "Earlier Sia accounts" lists those folders with Restore, which sets the
current account aside the same way and swaps the old one back.
Also: a fresh connect now records which indexer it used, and a "not
connected" check is re-run after 30 s so a login made outside Pithos
shows up.
The SigV4 encoder kept '/' unescaped in object paths by swapping in a
"never matches" regex (/$^/) for query values, but that regex matches the
empty string, so every empty query value went out as "/": prefix= became
prefix=/ and ?policy became ?policy=/. The request then no longer matched
what was signed, and listing any bucket or reading its policy failed
against s3d. Bucket listing and creation carry no query, so they worked.
Verified end to end against s3d (list, folders, upload, download, public
policy, folder delete) and against the aws cli; two regression tests.
Wherever a key pair is shown (the guide's last step, the key dialog) a
"Save credentials" button writes it to a .pithoskey file, and Users &
keys gains "Open saved credentials" to read one back.
- With a password (any host): PBKDF2-SHA256, 600k iterations, AES-256-GCM,
done in the page with WebCrypto.
- With the Theseus vault (default in Theseus): AES-256-GCM under a key the
add-on derives from the vault (pithos/credentials/v1, now fixed), so
there is no extra password; a locked vault raises the PIN prompt first.
The add-on saves through a native dialog, since the sidebar page has no
download path.
Only the user name and date stay readable, to tell files apart.
The account step's button read "I have an account — Next", folding a confirmation into navigation. It is a plain Next now, enabled by an explicit "I have created my Sia Storage account and I am signed in" checkbox (or by choosing your own indexer). Pithos cannot see the sia.storage tab to detect the sign-in itself, and the Connect step proves it anyway: approving needs a signed-in account.
Registers its panel with side: "left", so Theseus shows it in the quick-links strip beside the web apps instead of the right sidebar. Theseus builds without left panels ignore the field and keep it on the right.
In Theseus, Pithos now opens only with the vault unlocked: it asks
Theseus for the unlock (api.vault.requestUnlock), and Theseus shows its
own PIN prompt, falling back to the master password after three wrong
tries. Pithos never sees either. When the vault locks (Settings > Lock
now) Pithos locks within a few seconds; the add-on watches from the main
process because a hidden panel's timers run about once a minute.
The guide's phrase step gains "Use my Theseus vault" (the default when a
vault exists): the add-on derives the 12-word phrase from the vault
(purpose path pithos/sia-recovery/v1, first 16 bytes as BIP-39 entropy)
and hands it straight to s3d, so there is nothing to write down and the
vault backup restores storage access. The path is now fixed; changing it
would cut users off from their data.
Needs the vault-derive capability. On a Theseus without requestUnlock it
runs ungated, as before.
First run now lands on a step-by-step guide instead of the overview:
create a Sia Storage account (link out, Pithos never sees the password),
install s3d, choose or generate the recovery phrase, connect, start the
gateway and create the first access key, with Back/Next on every step.
The connect step opens the indexer's approval page on its own and moves
on as soon as the approval lands; where a browser blocks the pop-up it
says so and makes the button the primary action.
Hosts without node-pty (the Theseus add-on) now fetch the one platform
package they need from the npm registry on first login, pinned to its
published sha512 integrity, so the approval link can be read there too.
The console-window login stays only as the fallback when that fails.
A retry after a failed connect with an existing phrase goes back to the
phrase step: the phrase is not kept, and a blank one would make s3d
generate a new one.
In Theseus the console opened as a tab at http://127.0.0.1:<port>, a raw
local address in the URL bar. It is now a left-sidebar panel instead,
loading the add-on's own ui/index.html: API calls, uploads and live
events cross the add-on IPC bridge and the add-on forwards them to the
control server with an internal session. Downloads go to Theseus's
download manager through single-use 60-second links. The panel can widen
to full window or open as a tab.
The core gains internalSession() and downloadUrl() for that; web and
desktop hosts keep talking HTTP as before. Grids now shrink to fit, so
narrow hosts never scroll sideways.
The Theseus add-on ships updates on its own signed channel at navigate.st/bns/theseus.x/extensions/pithos/, so a Pithos fix never needs a Theseus release. 0.1.0 is the first entry.
s3d is driven entirely by a CLI and a two-route admin API, which keeps
Sia storage out of reach for anyone who does not live in a terminal.
Pithos wraps it: install the pinned s3d release (checksum verified),
start/stop and logs, indexer login, users and access keys, a bucket and
object browser with share links and public-read policies, and the
upload pipeline stats.
One control server (core/) serves one UI (ui/), and three hosts run it:
a web console, an Electron desktop window and a Theseus add-on, so a
feature lands everywhere at once. The server binds loopback, rejects
foreign Host headers, and signs views in with a one-time secret that
becomes a SameSite=Strict cookie. s3d login reads the recovery phrase
with term.ReadPassword, so it is driven through a pty, with a console
window fallback where the pty module is not shipped.