Files
Miles WardandClaude Opus 4.8 7751ebe9b3 v0.1.2: working Edit sheet, centred search, brand assets
Fixes a bug that shipped in v0.1: the per-account Edit sheet never opened at
all. Its Cancel button used `onclick: dlg.close`, evaluated while building the
arguments to openModal() and therefore before `const dlg` was initialised — a
temporal-dead-zone ReferenceError that aborted the whole handler. Every other
button in that sheet was already a closure, which is why it went unnoticed:
browser testing had covered add, import and settings, but never opened this
sheet.

Renames now reach Discord almost immediately. The push loop skips any account
whose current code it has already sent, so a rename previously stayed invisible
until the code next rolled — up to a full period. update() now clears the
last-sent code when the naming actually changes, so the next tick treats the
tile as stale and rewrites it in about a second. Toggling push alone is not a
rename and still costs nothing.

- webui: pencil icon and "Edit account" title so the row action reads as edit
  rather than settings; both fields labelled, with the second one explained as
  the username/email and left untouched unless changed
- webui: topbar is a three-column grid so the search sits on the same centre
  line as the account tiles. Below 820px there isn't room for brand + 420px
  search + actions, so it falls back to a row rather than clipping the
  wordmark; the brand now reads "Discord Authenticator" in full
- webui: the add-account FAB pins to the viewport corner instead of tracking
  the content column edge
- brand: docs/brand/icon.svg plus PNGs rendered from it by da-render, so the
  README image, Gitea avatar and Unraid template icon all derive from one
  source rather than drifting. Unraid's <Icon> now points at a PNG, which it
  renders more reliably than SVG

126 tests (was 124).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-31 01:42:18 -04:00

77 lines
4.0 KiB
XML

<?xml version="1.0"?>
<!--
Unraid Docker template for Discord Authenticator.
Drop this into /boot/config/plugins/dockerMan/templates-user/ on the Unraid
box, or add the repo as a template repository under Docker → Add Container.
Unlike OpenPXE this needs no host networking — it only makes outbound HTTPS
calls to Discord and serves one HTTP port, so bridge mode is correct.
Web UI: http://<unraid-ip>:8710/
-->
<Container version="2">
<Name>Discord-Authenticator</Name>
<Repository>gitea.milesward.dev/mward4/discord-authenticator:latest</Repository>
<Registry>https://gitea.milesward.dev/mward4/-/packages/container/discord-authenticator</Registry>
<Network>bridge</Network>
<MyIP/>
<Shell>sh</Shell>
<Privileged>false</Privileged>
<Support>https://gitea.milesward.dev/mward4/Discord-Authenticator/issues</Support>
<Project>https://gitea.milesward.dev/mward4/Discord-Authenticator</Project>
<Overview>
Self-hosted TOTP authenticator with live Discord delivery.
Add accounts by uploading a QR code, scanning with the camera, or pasting
an otpauth:// link. Google Authenticator exports are supported too: one
export QR carries many accounts, and you get a checklist to pick which to
import, with duplicates detected automatically. The web UI lists every
account with its rotating code, the way Google or Microsoft Authenticator
does.
The distinctive part: each account keeps ONE message in your Discord
channel, delivered through an incoming webhook and rewritten in place
every time the code rolls. Three accounts means three live tiles that
keep themselves current. The code is posted both as a rendered WebP tile
and as copyable text, and the countdown uses Discord's own relative
timestamps so it ticks in the client without any extra traffic.
SECURITY NOTE: anyone who can read that Discord channel can read these
codes, which is most of the point of a second factor. Use a private
channel in a server only you are in, and treat the webhook URL as a
secret. TOTP secrets are encrypted at rest with XChaCha20-Poly1305.
</Overview>
<Category>Tools:Utilities Security:</Category>
<WebUI>http://[IP]:[PORT:8710]/</WebUI>
<TemplateURL/>
<Icon>https://gitea.milesward.dev/mward4/Discord-Authenticator/raw/branch/main/docs/brand/icon-256.png</Icon>
<ExtraParams/>
<PostArgs/>
<CPUset/>
<DateInstalled/>
<DonateText/>
<DonateLink/>
<Requires>
A Discord incoming-webhook URL, from Server Settings → Integrations →
Webhooks → New Webhook → Copy Webhook URL. You can add it during first-run
setup or later in Settings.
</Requires>
<Config Name="WebUI Port" Target="8710" Default="8710" Mode="tcp"
Description="Port for the web UI and API."
Type="Port" Display="always" Required="true" Mask="false">8710</Config>
<Config Name="Data" Target="/var/lib/discord-authenticator"
Default="/mnt/user/appdata/discord-authenticator"
Mode="rw"
Description="Vault, encryption key, admin account and settings. BACK THIS UP — losing it loses every stored TOTP secret."
Type="Path" Display="always" Required="true" Mask="false">/mnt/user/appdata/discord-authenticator</Config>
<Config Name="Master key (optional)" Target="DA_MASTER_KEY" Default=""
Mode=""
Description="Base64 of 32 random bytes. Set this to keep the vault key OFF the appdata share, so a leaked backup of the share is useless on its own. Generate with: openssl rand -base64 32. Leave blank to auto-generate a key file inside the data folder instead. WARNING: if you set this later, existing secrets become unreadable — export them first."
Type="Variable" Display="advanced" Required="false" Mask="true"></Config>
<Config Name="Log filter" Target="DA_LOG" Default="info,da=info"
Mode=""
Description="tracing-subscriber EnvFilter expression. Use info,da=debug for more detail."
Type="Variable" Display="advanced" Required="false" Mask="false">info,da=info</Config>
</Container>