# Traefik dynamic route: client.gigafibre.ca → ERPNext (no Authentik) # # Purpose: Customer portal accessible without SSO. # Customers authenticate via a passwordless magic link (email/SMS) — the # Vue SPA's /#/login page posts to the hub, which mints a 24h JWT and # sends it back through a link the customer clicks. # # Staff continue to use id.gigafibre.ca / Authentik — NOT this host. # # Deploy: copy to /opt/traefik/dynamic/ on 96.125.196.67 # scp traefik-client-portal.yml root@96.125.196.67:/opt/traefik/dynamic/ # (Traefik auto-reloads dynamic config — no restart needed) # # DNS: *.gigafibre.ca wildcard already resolves to 96.125.196.67 # TLS: Let's Encrypt auto-provisions cert for client.gigafibre.ca http: routers: # Main portal router — NO authentik middleware client-portal: rule: "Host(`client.gigafibre.ca`)" entryPoints: - web - websecure service: client-portal-svc tls: certResolver: letsencrypt # Explicitly NO middlewares — customer auth is magic-link only # Block ERPNext's password /login page — we replaced it with a # passwordless flow at /#/login. Any stale bookmark or external link # that hits /login is bounced into the SPA's login route so customers # never see the password form (legacy MD5 hashes aren't supported # in the new flow — see docs/features/customer-portal.md). client-portal-block-login: rule: "Host(`client.gigafibre.ca`) && (Path(`/login`) || Path(`/login/`))" entryPoints: - web - websecure service: client-portal-svc middlewares: - portal-redirect-magic-login tls: certResolver: letsencrypt priority: 300 # Block ERPNext's password-reset page (equivalent path, same reason) client-portal-block-update-password: rule: "Host(`client.gigafibre.ca`) && PathPrefix(`/update-password`)" entryPoints: - web - websecure service: client-portal-svc middlewares: - portal-redirect-magic-login tls: certResolver: letsencrypt priority: 300 # Block /desk access for portal users client-portal-block-desk: rule: "Host(`client.gigafibre.ca`) && PathPrefix(`/desk`)" entryPoints: - web - websecure service: client-portal-svc middlewares: - portal-redirect-home tls: certResolver: letsencrypt priority: 200 middlewares: # Redirect /login + /update-password → SPA's magic-link request page. # The SPA lives at /assets/client-app/ (see apps/client/deploy.sh); its # hash router serves /#/login. portal-redirect-magic-login: redirectRegex: regex: ".*" replacement: "https://client.gigafibre.ca/#/login" permanent: false # Redirect /desk attempts to portal home portal-redirect-home: redirectRegex: regex: ".*" replacement: "https://client.gigafibre.ca/me" permanent: false services: # Same ERPNext frontend container, unique service name to avoid # conflicts with Docker-label-defined services client-portal-svc: loadBalancer: servers: - url: "http://erpnext-frontend-1:8080"