gitea/templates/user/settings/account.tmpl
Rowan Bohde 1ee59f0fa3
Allow disabling authentication related user features (#31535)
We have some instances that only allow using an external authentication
source for authentication. In this case, users changing their email,
password, or linked OpenID connections will not have any effect, and
we'd like to prevent showing that to them to prevent confusion.

Included in this are several changes to support this:
* A new setting to disable user managed authentication credentials
(email, password & OpenID connections)
* A new setting to disable user managed MFA (2FA codes & WebAuthn)
* Fix an issue where some templates had separate logic for determining
if a feature was disabled since it didn't check the globally disabled
features
* Hide more user setting pages in the navbar when their settings aren't
enabled

---------

Co-authored-by: Kyle D <kdumontnu@gmail.com>
2024-07-09 17:36:31 +00:00

188 lines
8.3 KiB
Handlebars

{{template "user/settings/layout_head" (dict "ctxData" . "pageClass" "user settings account")}}
<div class="user-setting-content">
<h4 class="ui top attached header">
{{ctx.Locale.Tr "settings.password"}}
</h4>
<div class="ui attached segment">
{{if and (not ($.UserDisabledFeatures.Contains "manage_credentials")) (or (.SignedUser.IsLocal) (.SignedUser.IsOAuth2))}}
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/user/settings/account" method="post">
{{template "base/disable_form_autofill"}}
{{.CsrfTokenHtml}}
{{if .SignedUser.IsPasswordSet}}
<div class="required field {{if .Err_OldPassword}}error{{end}}">
<label for="old_password">{{ctx.Locale.Tr "settings.old_password"}}</label>
<input id="old_password" name="old_password" type="password" autocomplete="current-password" autofocus required>
</div>
{{end}}
<div class="required field {{if .Err_Password}}error{{end}}">
<label for="password">{{ctx.Locale.Tr "settings.new_password"}}</label>
<input id="password" name="password" type="password" autocomplete="new-password" required>
</div>
<div class="required field {{if .Err_Password}}error{{end}}">
<label for="retype">{{ctx.Locale.Tr "settings.retype_new_password"}}</label>
<input id="retype" name="retype" type="password" autocomplete="new-password" required>
</div>
<div class="field">
<button class="ui primary button">{{ctx.Locale.Tr "settings.change_password"}}</button>
<a href="{{AppSubUrl}}/user/forgot_password?email={{.Email}}">{{ctx.Locale.Tr "auth.forgot_password"}}</a>
</div>
</form>
{{else}}
<div class="ui info message">
<p class="text left">{{ctx.Locale.Tr "settings.password_change_disabled"}}</p>
</div>
{{end}}
</div>
{{if not (and ($.UserDisabledFeatures.Contains "manage_credentials") (not $.EnableNotifyMail))}}
<h4 class="ui top attached header">
{{ctx.Locale.Tr "settings.manage_emails"}}
</h4>
<div class="ui attached segment">
<div class="ui list">
{{if $.EnableNotifyMail}}
<div class="item">
<div class="tw-mb-2">{{ctx.Locale.Tr "settings.email_desc"}}</div>
<form action="{{AppSubUrl}}/user/settings/account/email" class="ui form" method="post">
{{$.CsrfTokenHtml}}
<input name="_method" type="hidden" value="NOTIFICATION">
<div class="tw-flex tw-flex-wrap tw-gap-2">
<div class="ui selection dropdown">
<input name="preference" type="hidden" value="{{.EmailNotificationsPreference}}">
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="text"></div>
<div class="menu">
<div data-value="enabled" class="{{if eq .EmailNotificationsPreference "enabled"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.enable"}}</div>
<div data-value="andyourown" class="{{if eq .EmailNotificationsPreference "andyourown"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.andyourown"}}</div>
<div data-value="onmention" class="{{if eq .EmailNotificationsPreference "onmention"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.onmention"}}</div>
<div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.disable"}}</div>
</div>
</div>
<button class="ui primary button">{{ctx.Locale.Tr "settings.email_notifications.submit"}}</button>
</div>
</form>
</div>
{{end}}
{{if not ($.UserDisabledFeatures.Contains "manage_credentials")}}
{{range .Emails}}
<div class="item">
{{if not .IsPrimary}}
<div class="right floated content">
<button class="ui red tiny button delete-button" data-modal-id="delete-email" data-url="{{AppSubUrl}}/user/settings/account/email/delete" data-id="{{.ID}}">
{{ctx.Locale.Tr "settings.delete_email"}}
</button>
</div>
{{if .CanBePrimary}}
<div class="right floated content">
<form action="{{AppSubUrl}}/user/settings/account/email" method="post">
{{$.CsrfTokenHtml}}
<input name="_method" type="hidden" value="PRIMARY">
<input name="id" type="hidden" value="{{.ID}}">
<button class="ui primary tiny button">{{ctx.Locale.Tr "settings.primary_email"}}</button>
</form>
</div>
{{end}}
{{end}}
{{if not .IsActivated}}
<div class="right floated content">
<form action="{{AppSubUrl}}/user/settings/account/email" method="post">
{{$.CsrfTokenHtml}}
<input name="_method" type="hidden" value="SENDACTIVATION">
<input name="id" type="hidden" value="{{.ID}}">
{{if $.ActivationsPending}}
<button disabled class="ui primary tiny button">{{ctx.Locale.Tr "settings.activations_pending"}}</button>
{{else}}
<button class="ui primary tiny button">{{ctx.Locale.Tr "settings.activate_email"}}</button>
{{end}}
</form>
</div>
{{end}}
<div class="content tw-py-2">
<strong>{{.Email}}</strong>
{{if .IsPrimary}}
<div class="ui primary label">{{ctx.Locale.Tr "settings.primary"}}</div>
{{end}}
{{if .IsActivated}}
<div class="ui green label">{{ctx.Locale.Tr "settings.activated"}}</div>
{{else}}
<div class="ui label">{{ctx.Locale.Tr "settings.requires_activation"}}</div>
{{end}}
</div>
</div>
{{end}}
{{end}}
</div>
</div>
{{end}}
{{if not ($.UserDisabledFeatures.Contains "manage_credentials")}}
<div class="ui bottom attached segment">
<form class="ui form" action="{{AppSubUrl}}/user/settings/account/email" method="post">
{{.CsrfTokenHtml}}
<div class="required field {{if .Err_Email}}error{{end}}">
<label for="email">{{ctx.Locale.Tr "settings.add_new_email"}}</label>
<input id="email" name="email" type="email" required {{if not .CanAddEmails}}disabled{{end}}>
</div>
<button class="ui primary button" {{if not .CanAddEmails}}disabled{{end}}>
{{ctx.Locale.Tr "settings.add_email"}}
</button>
</form>
{{/* if ActivationsPending is false, then CanAddEmails must be true, so if CanAddEmails is false, ActivationsPending must be true */}}
{{if not .CanAddEmails}}
<div class="ui warning message">{{ctx.Locale.Tr "settings.can_not_add_email_activations_pending"}}</div>
{{end}}
</div>
{{end}}
{{if not ($.UserDisabledFeatures.Contains "deletion")}}
<h4 class="ui top attached error header">
{{ctx.Locale.Tr "settings.delete_account"}}
</h4>
<div class="ui attached error segment">
<div class="ui red message">
<p class="text left">{{svg "octicon-alert"}} {{ctx.Locale.Tr "settings.delete_prompt"}}</p>
{{if .UserDeleteWithComments}}
<p class="text left tw-font-semibold">{{ctx.Locale.Tr "settings.delete_with_all_comments" .UserDeleteWithCommentsMaxTime}}</p>
{{end}}
</div>
<form class="ui form ignore-dirty" id="delete-form" action="{{AppSubUrl}}/user/settings/account/delete" method="post">
{{template "base/disable_form_autofill"}}
{{.CsrfTokenHtml}}
<div class="required field {{if .Err_Password}}error{{end}}">
<label for="password-confirmation">{{ctx.Locale.Tr "password"}}</label>
<input id="password-confirmation" name="password" type="password" autocomplete="off" required>
</div>
<div class="field">
<button class="ui red button delete-button" data-modal-id="delete-account" data-type="form" data-form="#delete-form">
{{ctx.Locale.Tr "settings.confirm_delete_account"}}
</button>
</div>
</form>
<div class="ui g-modal-confirm delete modal" id="delete-account">
<div class="header">
{{svg "octicon-trash"}}
{{ctx.Locale.Tr "settings.delete_account_title"}}
</div>
<div class="content">
<p>{{ctx.Locale.Tr "settings.delete_account_desc"}}</p>
</div>
{{template "base/modal_actions_confirm" .}}
</div>
</div>
{{end}}
</div>
<div class="ui g-modal-confirm delete modal" id="delete-email">
<div class="header">
{{svg "octicon-trash"}}
{{ctx.Locale.Tr "settings.email_deletion"}}
</div>
<div class="content">
<p>{{ctx.Locale.Tr "settings.email_deletion_desc"}}</p>
</div>
{{template "base/modal_actions_confirm" .}}
</div>
{{template "user/settings/layout_footer" .}}