Releases: Solutionmax/amfora
Release list
Amfora 2.2.0
Amfora 2.2.0
Updating shows its progress, step by step.
- Update now opens a progress dialog, the same one Pharos and Ostia show: update requested,
handing over to the server, checking the signed release, backing up your data, downloading
the new version, restarting Amfora, checking that it is healthy. A spinner marks the current
step, finished steps get a green check, the elapsed time runs in the corner. It ends with
"installed" and a Reload button, or with the reason it stopped while the previous version
keeps running. - It keeps going while Amfora restarts, and opens again when you come back to Settings during
an install. - No change on the host: the app reads the progress from the update log the host side already
writes, so existing over the air installations get the dialog without reinstalling anything. - New admin route
GET /update/progress.
The dialog belongs to the version that runs the update, so you see it from the update after
this one.
Image: ghcr.io/solutionmax/amfora:2.2.0 (linux/amd64, linux/arm64).
Amfora 2.1.0
Amfora 2.1.0
Your own picture on every download page, and videos that download instead of play.
Download page cover
- Customization has a new Download page section. Upload one image and it becomes the cover
at the top of every download page, with the file name over it. Without a cover the page shows
your accent colour with a large icon for the file type. - Files from a share are never used as the cover any more.
No playing in the browser
- New switch Play video and audio on download pages, off by default, also for existing
installations. While it is off, download pages show no play button and no Preview button for
video and audio, and the server refuses to stream them to visitors. Downloading works as
always; images, PDFs and text keep their preview; you still preview your own files in the
workspace.
Link previews
- When a download or receive link is pasted into WhatsApp, Slack or similar apps, the preview
image is your cover. Without a cover it is the new Default link preview image you can upload
under Customization, then your logo, then the Amfora card. A file from the share is never shown. - Apps cache previews, so a link that was already shared may keep its old image for a while.
Both images are part of the free version. Uploads are checked by content (PNG, JPEG, WebP, GIF,
AVIF), at least 600 px wide, up to 3 MB.
Update
With over the air updates, install 2.1.0 from the admin area. Otherwise set the version in your
compose file and run docker compose pull && docker compose up -d. Existing installations start
with playing switched off; turn it on under Customization if you want it.
Image: ghcr.io/solutionmax/amfora:2.1.0 (linux/amd64, linux/arm64).
Amfora 2.0.1
Amfora 2.0.1
A security and install release. Update if you run 2.0.0.
Security
- The brandpack key is built into the server.
AMFORA_BRANDPACK_PUBLIC_KEYno longer exists,
so a key pair of your own and a self signed pack are refused by the published image. - Administrator checks read the account from the database on every request. A demoted or
deactivated administrator loses access at once, instead of when the one day session ends.
This covers the app settings, updates, users, invitations and the storage overview. - The unused
/s3/*routes are gone. They offered presigned upload and download links and a
delete for any object without a session; the web app never called them and the API port is
not published by default, but they no longer exist to be reached. - Registering the first administrator closes the setup window on the server. It used to wait
for the browser to switch it off, so an account created through the API left settings such as
the SMTP password readable without a session. - Tests for the administrator guard (including the first run exception), for these routes and
for the attachment rule that keeps uploaded HTML and SVG from running in the browser.
Install
-
Fresh installs without
AMFORA_UIDstart again. The server fell back to uid 1000 while
the bundled storage runs as the amfora user, so a new installation could not read its storage
credentials and never came up. Existing installations that setAMFORA_UIDwere not affected.
CI now starts the image exactly as the installer does before anything is released. -
The installer pulls the published image by default, pinned to the current release: Docker
with Compose v2 is all you need, and a new install starts in about a minute instead of a
twenty minute build.--sourcestill builds, now from the release tag instead of the tip of
the branch. -
docker-compose.yamlin the repository uses the published image; setAMFORA_IMAGEto run
your own build. -
The README and the docs explain how to update.
Website
- The site can be found by search engines, has a sitemap, a proper link preview image and
icons, loads its screenshots lazily and no longer trips its own content security policy. - New page: moving from Palmr (
/palmr/). - Buying the brandpack or setup opens a confirmation page first; only its button starts a
Stripe checkout, so link previews and crawlers no longer create payment sessions.
Update
With over the air updates, install 2.0.1 from the admin area. Otherwise set the version in your
compose file and run docker compose pull && docker compose up -d. Your data stays in place.
Image: ghcr.io/solutionmax/amfora:2.0.1 (linux/amd64, linux/arm64).
Amfora 2.0.0
Amfora 2.0.0
A new interface, front and back, and a white-label model that runs on the server.
New interface
- Public pages (sign-in, download, receive, recovery, invitations) are built as a statement
column and a floating panel on a soft colour wash in the installation's accent. Downloads
open with a cover: an image file is its own cover, anything else gets the accent gradient.
Files are listed as a manifest with type tiles, sublines and a total line. - The workspace has a tinted sidebar, a page header with a subline, and the same panels and
tables everywhere. The dashboard greets by time of day, opens with "Send files" and
"Receive files", and shows storage, shares, downloads and files in one strip. - Family palette shared with the other SolutionMAX products: accent
#0079D2, ink
#0C1626. Archivo for headings, Public Sans for text, JetBrains Mono for numbers.
Light and dark are both finished. - The postal artwork, envelopes, stamps and quotes are gone. The uploaded logo replaces the
mark everywhere, including the favicon and link previews.
Workspace details
- Receive links are wide rows: status, name, the link with copy, QR and open, chips for
files, size, limit, protection and end date, and the received files listed inline. - Tables keep their actions column on screen at laptop widths instead of scrolling sideways.
Appearance on the server
- Name, description, logo, accent colour, corner radius and font were already stored per
installation. The public-page background, the custom CSS and the credit setting now are too;
nothing brand-related lives in the browser any more. - New endpoints:
GET/POST/DELETE /app/background,PUT/DELETE /app/brandpack. The web app
serves the logo at/api/app/logoand the background at/api/app/background. - Defaults changed for new installations: accent
#0079d2(was#1757e8), radius0.5rem
(was0.75rem), no default logo (the mark is drawn). Existing installations keep their
stored colour and radius; the 1.x default logo is recognised and reset so the mark shows.
Brandpack
- A brandpack is a signed string a customer pastes under Customization. With a valid one the
installation can hide "Powered by Amfora", set a background image for the public pages and
add custom CSS. Without one those settings are ignored by the server, whatever is stored. - Custom CSS is sanitised on the server: CSS escape sequences are decoded first so
\75rl(
cannot hideurl(, then@import, outsideurl(,expression(,behavior:and
-moz-bindingare removed, every<is written as the CSS escape\3cso the style
element can never be closed from inside, and the size is capped at 20 kB. - The background upload checks the file signature (PNG, JPEG, WebP, GIF, AVIF) rather than
the client's content type, so SVG never reaches the image library, and decoding has a
pixel limit. The brandpack and background routes require a signed-in administrator with
no first-run exception. Seedocs/BRANDPACK.md. - Buying one: https://amfora.solutionmax.net/brandpack/.
Security
- The admin guard on the application settings routes skipped authentication whenever the
installation had one user or fewer, which is every single-admin installation: the
configuration, including the SMTP password, could be read and changed without a session.
The exception now applies only during first run. Upgrade for this alone. - Files that recipients upload through a receive link are streamed as an attachment with a
sandbox policy when they are html, svg, xml or javascript, so an uploaded page can never run
on the application origin when an administrator opens it. - Custom CSS (new in 2.0) is escaped so it can never close its style element, and CSS escape
sequences are decoded before the filter runs.
Upgrading
Pull the image or press Update. prisma db push adds nothing new; three app configs are
seeded on start. No data changes. The customization page is new; the theme switch moved to
the sidebar, and the per-browser background colours were dropped in favour of the server-side
background image.
Amfora 1.2.0
Amfora 1.2.0
Amfora 1.2.0 answers a question an owner could not answer before: was my file actually
collected? It also stops the dashboard hiding everything past the fifth row, and adds an
update check so an installation can tell you a new release exists.
Download counts
- A file now carries a download count, visible to its owner in the file list and the grid.
It is a plain number. No address, no user agent, no timestamp, nothing about who collected
the file. - The count is never part of a public share response, so a recipient cannot see how many
others were there before them. - Counted is the moment a download starts. Previews, embeds and the owner fetching their own
file are excluded, as is a player seeking through a video. A second click within the same
visit reuses the URL the first click was given, so it counts once; a fresh visit counts again. - The share page used to print the page view count under a "Downloads" label. That label now
reads Views, because a real download count exists.
Dashboard
- Recent Uploads and Recent Shares page through the whole list five at a time. They already
held every file and share, and cut the list to five, so the rest was in the browser with no
way to reach it. - The running version is shown at the bottom of the menu, and disappears with the existing
setting that already hides it in the footer.
Update checking
- An administrator sees in Settings whether a newer release exists. The release manifest is
Ed25519 signed and names an image digest rather than a tag, so what an installation is told
to run is exactly what was published. - Checking is the only thing this does on its own. The request carries nothing about the
installation, and an emptyAMFORA_UPDATE_URLswitches it off completely. - Applying updates from the app is optional and needs a one time install on the host. The
container is never given the Docker socket, which would be root on the host for an
application that accepts public uploads. Seedocs/OTA.md.
Before you upgrade
A downloads column is added to the file table at startup, with a default of zero. Existing
files therefore start at zero even if they were collected before this release: there is no
record of earlier downloads to recover.
Nothing else changes, and no configuration is required.
Validation
Lint, TypeScript and the automated suites of both applications, including new unit tests for
download counting, preview URLs, release manifest verification and version comparison.
Verified against a live deployment behind a reverse proxy: a real click on a share page's
download button raises the count by one, a second click in the same visit does not, a reload
and another click does, a preview does not, and an owner fetching their own file does not.
The update path was exercised end to end in an isolated Compose project, including signature
refusal for a forged manifest and the database backup taken before the pull.
Amfora 1.1.0
Amfora 1.1.0
Amfora 1.1.0 repairs link previews. Every share and reverse share link pasted into a chat now carries a real preview image instead of a broken one, and a share holding a single image can show that image as its own preview.
Link previews
og:imageno longer carries the app logo verbatim. An uploaded logo is stored as adata:URI, and unfurl bots fetch preview images over HTTP, so Slack, WhatsApp, Discord and LinkedIn rendered a broken image for every link. Previews are now always an absolute URL.- Anything that is not an
httporhttpslogo falls back to a bundled 1200x630 card. This also corrects a square logo being announced as a widesummary_large_imagepreview. - A share that holds exactly one image can use that image as its preview. Reverse share links keep the card, since they hold no content when the link is shared.
Preview safety
Unfurl bots are anonymous, and their result is rendered in whatever channel the link was pasted into. A share only qualifies for a file preview when it carries no password, has not expired, sets no view limit, holds no folders, holds exactly one file, that file is an image, and it is at most 5 MB. Password protected shares fall back to the card, so content never reaches a channel before the recipient has entered the password. View limited shares are excluded as well, so a bot cannot spend one of the owner's permitted views.
Operator notes
STORAGE_URL must be an address the visitor's browser can reach, not only the container. An internal address produces a working share page whose download and upload both fail for anyone outside the network. This was already documented, and the startup error for a missing value now matters more with previews in play, since the preview URL is fetched by third party services.
Validation
Lint, TypeScript, and the automated test suites of both applications, including new unit tests for preview eligibility and preview URL construction. Verified against a live deployment behind a reverse proxy: a video share falls back to the card, an image share serves the image to an anonymous client identifying as an unfurl bot, and adding a password moves that same share back to the card while the direct download returns 401.
Amfora 1.0.0
Amfora 1.0.0 combines the unified website, login and transfer design with the security fixes from the release audit.
- Protected share downloads, uploads bound to server authorization and atomic upload quotas.
- Password verification challenges for 2FA, protected remembered device tokens and provider management restricted to administrators.
- Canonical reset links, escaped mail templates and explicit proxy trust.
- Updated production dependencies: zero known vulnerabilities in both JavaScript package audits.
Validation: 68 automated tests, isolated security regressions, a real 101 MiB multipart transfer, concurrent quota checks, local SMTP delivery, and desktop/mobile browser checks. See the attached validation summary and release/upgrade notes for scope and configuration requirements.
Back up application data before upgrading. Set APP_URL to the actual application origin. Existing remembered devices must authenticate again.