commit e360ab67cd3503b944abdfeb70ca640ba66a2948
parent ec3924678206fc34fe0505ab897639a846f2df80
Author: Silas Brack <silasbrack@gmail.com>
Date: Sun, 31 May 2026 22:22:46 +0200
feat: implement email verification using local server
Diffstat:
3 files changed, 72 insertions(+), 21 deletions(-)
diff --git a/config/runtime.exs b/config/runtime.exs
@@ -103,15 +103,33 @@ if config_env() == :prod do
#
# Check `Plug.SSL` for all available options in `force_ssl`.
- config :daily_tracker, DailyTracker.Mailer,
- adapter: Swoosh.Adapters.SMTP,
- relay: System.get_env("MAIL_HOST", "mail.silasbrack.com"),
- port: 25,
- username: "silas@silasbrack.com",
- password: System.get_env("MAIL_PASSWORD") ||
- raise("environment variable MAIL_PASSWORD is missing."),
- tls: :always,
- ssl: false,
- tls_options: [cacerts: :public_key.cacerts_get()],
- auth: :always
+ mail_host = System.get_env("MAIL_HOST", "mail.silasbrack.com")
+
+ mail_config =
+ if mail_host == "localhost" do
+ # Local delivery on the same machine — no TLS or auth needed
+ [
+ adapter: Swoosh.Adapters.SMTP,
+ relay: "localhost",
+ port: 25,
+ tls: :never,
+ ssl: false,
+ auth: :never
+ ]
+ else
+ [
+ adapter: Swoosh.Adapters.SMTP,
+ relay: mail_host,
+ port: 25,
+ username: "silas@silasbrack.com",
+ password: System.get_env("MAIL_PASSWORD") ||
+ raise("environment variable MAIL_PASSWORD is missing."),
+ tls: :always,
+ ssl: false,
+ tls_options: [cacerts: :public_key.cacerts_get()],
+ auth: :always
+ ]
+ end
+
+ config :daily_tracker, DailyTracker.Mailer, mail_config
end
diff --git a/flake.lock b/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1779796641,
+ "narHash": "sha256-ZsIrKmhp4vbBXoXXmR/tBXA/UCsAQiJL9vsgZEduhVY=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "25f538306313eae3927264466c70d7001dcea1df",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-25.11",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
@@ -10,11 +10,6 @@
pkgs = import nixpkgs { inherit system; };
beamPackages = pkgs.beamPackages;
- mixNixDeps = import ./deps.nix {
- inherit (pkgs) lib;
- inherit beamPackages;
- };
-
heroicons = pkgs.fetchFromGitHub {
owner = "tailwindlabs";
repo = "heroicons";
@@ -28,18 +23,29 @@
version = "0.1.0";
src = ./.;
- inherit mixNixDeps;
+ removeCookie = false;
+
+ mixFodDeps = beamPackages.fetchMixDeps {
+ pname = "daily_tracker-deps";
+ version = "0.1.0";
+ src = ./.;
+ sha256 = "sha256-UnNtgwAkJDF77MmtkC0Cy/aZ0J7jx/8fZEX2uVNhLNY=";
+ };
- # Handle the heroicons git dep that mix2nix can't generate
- postConfigure = ''
- mkdir -p deps/heroicons
- cp -r ${heroicons}/optimized/* deps/heroicons/
+ # Replace heroicons git dep with a path dep before any mix phase runs
+ postPatch = ''
+ sed -i '/heroicons/d' mix.lock
+ sed -i '/:heroicons/,/depth: 1}/c\ {:heroicons, path: "${heroicons}/optimized", app: false, compile: false},' mix.exs
'';
# Build assets before release
preBuild = ''
export MIX_ESBUILD_PATH="${pkgs.esbuild}/bin/esbuild"
export TAILWIND_PATH="${pkgs.tailwindcss_4}/bin/tailwindcss"
+
+ # Compile first so colocated hooks are generated
+ mix compile --no-deps-check
+
mix assets.deploy --no-deps-check
'';
};