Skip to content

Releases: Solutionmax/amfora

Amfora 2.2.0

Choose a tag to compare

@raym0nz82 raym0nz82 released this 22 Sep 23:32

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

Choose a tag to compare

@raym0nz82 raym0nz82 released this 22 Sep 21:49

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

Choose a tag to compare

@raym0nz82 raym0nz82 released this 22 Sep 20:46

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_KEY no 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_UID start 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 set AMFORA_UID were 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. --source still builds, now from the release tag instead of the tip of
    the branch.

  • docker-compose.yaml in the repository uses the published image; set AMFORA_IMAGE to 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

Choose a tag to compare

@raym0nz82 raym0nz82 released this 22 Sep 07:13

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/logo and the background at /api/app/background.
  • Defaults changed for new installations: accent #0079d2 (was #1757e8), radius 0.5rem
    (was 0.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 hide url(, then @import, outside url(, expression(, behavior: and
    -moz-binding are removed, every < is written as the CSS escape \3c so 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. See docs/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

Choose a tag to compare

@raym0nz82 raym0nz82 released this 21 Sep 17:23

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 empty AMFORA_UPDATE_URL switches 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. See docs/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

Choose a tag to compare

@raym0nz82 raym0nz82 released this 21 Sep 12:02

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:image no longer carries the app logo verbatim. An uploaded logo is stored as a data: 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 http or https logo falls back to a bundled 1200x630 card. This also corrects a square logo being announced as a wide summary_large_image preview.
  • 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

Choose a tag to compare

@raym0nz82 raym0nz82 released this 17 Sep 20:27

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.