Let Authentik own forward-auth user emails; add forward-auth tests

For SSO users the email address is the IdP match key, so allowing them
to edit it in Veola orphaned the row on next sign-in. PostEmailPrefs now
keeps the synced Authentik email for forward users (only the deal-alert
and digest toggles stay editable); the settings form renders the field
read-only with a Managed by Authentik note. Local break-glass users keep
an editable field.

Add forward-auth integration tests over the full Routes() chain: trusted
proxy provisions an admin, untrusted peer's spoofed headers are ignored,
role re-syncs per request, and the email-prefs round trip confirms a form
cannot change a forward user's IdP email.
This commit is contained in:
prosolis
2026-06-20 11:26:02 -07:00
parent 7c95e4fd4e
commit 2fd4019103
4 changed files with 364 additions and 91 deletions

View File

@@ -206,8 +206,13 @@ templ settingsBody(d SettingsData) {
@CSRFInput(d.CSRFToken)
<div>
<label class="v-label">Notification Email</label>
<input class="v-input" type="email" name="email" value={ currentEmail(d) } placeholder="you@example.com"/>
<div class="v-muted text-xs mt-1">Where deal alerts and the weekly digest are sent. Requires Resend to be configured by an admin.</div>
if emailManagedExternally(d) {
<input class="v-input" type="email" value={ currentEmail(d) } disabled/>
<div class="v-muted text-xs mt-1">Managed by Authentik. Change your email in your Authentik profile; it syncs here on next sign-in.</div>
} else {
<input class="v-input" type="email" name="email" value={ currentEmail(d) } placeholder="you@example.com"/>
<div class="v-muted text-xs mt-1">Where deal alerts and the weekly digest are sent. Requires Resend to be configured by an admin.</div>
}
</div>
<label class="flex items-center gap-2">
<input type="checkbox" name="email_deal_alerts" value="1" checked?={ currentDealAlerts(d) }/>
@@ -294,6 +299,13 @@ func currentWeeklyDigest(d SettingsData) bool {
return d.CurrentUser != nil && d.CurrentUser.EmailWeeklyDigest
}
// emailManagedExternally reports whether the signed-in user's email comes from
// an identity provider (Authentik forward-auth) and so is read-only here. The
// address is the IdP match key; letting them edit it would orphan the row.
func emailManagedExternally(d SettingsData) bool {
return d.CurrentUser != nil && d.CurrentUser.AuthSource == "forward"
}
templ Settings(d SettingsData) {
@Layout(d.Page, settingsBody(d))
}