dangkhoabach.vn — Personal Platform
The site you are on: one ASP.NET Core API and eight Next.js apps on separate subdomains — this portfolio, ToolsHub, an app download centre, a small random-picker game, a Vietnamese and English text-to-speech site, a private film library, one account site that signs in to all of them and an admin console that also runs my home lab.

- Type
- Personal project
- Period
- 07/2026 – present
- Built with
- Links
- dangkhoabach.vn
What I built
- Portfolio with server rendering, EN/VI, light and dark themes, structured data and a fallback snapshot when the API is down.
- Accounts: one sign-in for every site, with an email or username and then an authenticator code or a passkey. Each site receives a one-time code, and only users granted that app get in; profile pictures, passwords, 2FA and the sessions of every site are managed in one place.
- Text to Speech: Vietnamese and English speech in a fast and a high-quality mode, free to try without an account behind Cloudflare Turnstile; signed-in users get personal API tokens and daily usage. The voices run on my home NAS.
- Movies: a private film library by folder, with 4K, HDR, Dolby Vision and Atmos tags; users granted access stream from the NAS through a personal link they can renew at any time.
- Admin console: content editing, contact inbox, users and the apps each one may open, audit log with before/after diffs, email log and app releases.
- Insights: cookie-less analytics for all public sites. Visitors are counted with a daily-rotating salted hash, so no IP address is stored.
- App releases: publish a macOS build, its Sparkle feed and release notes; the download page refreshes immediately and downloads are counted.
- Home & NAS: live status of my home lab, its containers, disks and datasets, email alerts and 15 allowlisted remote commands (see the Home Lab on TrueNAS project).
Security
- Opaque, hashed, revocable sessions; Argon2id; lockout and rate limits.
- TOTP MFA with encrypted secrets and single-use recovery codes; passkeys (WebAuthn) for passwordless sign-in and Touch ID step-up.
- Sensitive commands need a fresh MFA or passkey check; every write is audited in the same database transaction.
- The admin, Accounts, Text to Speech and Movies sites call the API only from their servers, each with its own shared secret and CSRF value, and a per-request nonce CSP.
- A film link is an HMAC of the user and a version number, so the API stores no links; renewing one stops the old link within a minute.
- Uploads are checked by magic bytes and re-encoded without their metadata; SVGs are sanitised and re-serialised.
Delivery
- 335 API tests (xUnit).
- Scripted deploys to Windows IIS: standalone Next.js builds under iisnode, incremental uploads, API swaps behind an offline page and post-deploy checks.