wekan/client/components/settings/settingBody.jade
Lauri Ojansivu ae0d059b6f Feature: Added brute force login protection settings to Admin Panel/People/Locked Users.
Added filtering of Admin Panel/People/People: All Users/Locked Users Only/Active/Not Active.
Added visual indicators: red lock icon for locked users, green check for active users, and red X for inactive users.
Added "Unlock All" button to quickly unlock all brute force locked users.
Added ability to toggle user active status directly from the People page.
Moved lockout settings from environment variables to database so admins can configure the lockout thresholds directly in the UI.

Thanks to xet7.
2025-08-05 00:31:43 +03:00

316 lines
14 KiB
Text

template(name="setting")
.setting-content
unless currentUser.isAdmin
| {{_ 'error-notAuthorized'}}
else
.content-title
i.fa.fa-cog
span {{_ 'settings'}}
.content-body
.side-menu
ul
li.active
a.js-setting-menu(data-id="registration-setting")
i.fa.fa-sign-in
| {{_ 'registration'}}
unless isSandstorm
li
a.js-setting-menu(data-id="email-setting")
i.fa.fa-envelope
| {{_ 'email'}}
li
a.js-setting-menu(data-id="account-setting")
i.fa.fa-users
| {{_ 'accounts'}}
li
a.js-setting-menu(data-id="tableVisibilityMode-setting")
i.fa.fa-eye
| {{_ 'tableVisibilityMode'}}
li
a.js-setting-menu(data-id="announcement-setting")
i.fa.fa-bullhorn
| {{_ 'admin-announcement'}}
li
a.js-setting-menu(data-id="accessibility-setting")
i.fa.fa-universal-access
| {{_ 'accessibility'}}
li
a.js-setting-menu(data-id="layout-setting")
i.fa.fa-object-group
| {{_ 'layout'}}
li
a.js-setting-menu(data-id="webhook-setting")
i.fa.fa-globe
| {{_ 'global-webhook'}}
.main-body
if loading.get
+spinner
else if generalSetting.get
+general
else if emailSetting.get
unless isSandstorm
+email
else if accountSetting.get
+accountSettings
else if tableVisibilityModeSetting.get
+tableVisibilityModeSettings
else if announcementSetting.get
+announcementSettings
else if accessibilitySetting.get
+accessibilitySettings
else if layoutSetting.get
+layoutSettings
else if webhookSetting.get
+webhookSettings
template(name="webhookSettings")
span
+outgoingWebhooksPopup
template(name="general")
ul#registration-setting.setting-detail
li
a.flex.js-toggle-forgot-password
.materialCheckBox(class="{{#if currentSetting.disableForgotPassword}}is-checked{{/if}}")
span {{_ 'disable-forgot-password'}}
li
a.flex.js-toggle-registration
.materialCheckBox(class="{{#if currentSetting.disableRegistration}}is-checked{{/if}}")
span {{_ 'disable-self-registration'}}
li
.invite-people(class="{{#if currentSetting.disableRegistration}}{{else}}hide{{/if}}")
ul
li
.title {{_ 'invite-people'}}
textarea#email-to-invite.wekan-form-control(rows='5', placeholder="{{_ 'email-addresses'}}")
li
.title {{_ 'to-boards'}}
.bg-white
each boards
a.option.flex.js-toggle-board-choose(id= _id)
.materialCheckBox(data-id= _id)
span= title
li
button.js-email-invite.primary {{_ 'invite'}}
template(name='email')
ul#email-setting.setting-detail
//if isSandstorm
// li.smtp-form
// .title {{_ 'smtp-host'}}
// .description {{_ 'smtp-host-description'}}
// .form-group
// input.wekan-form-control#mail-server-host(type="text", placeholder="smtp.domain.com" value="{{currentSetting.mailServer.host}}")
// li.smtp-form
// .title {{_ 'smtp-port'}}
// .description {{_ 'smtp-port-description'}}
// .form-group
// input.wekan-form-control#mail-server-port(type="text", placeholder="25" value="{{currentSetting.mailServer.port}}")
// li.smtp-form
// .title {{_ 'smtp-username'}}
// .form-group
// input.wekan-form-control#mail-server-u"accounts-allowUserNameChange": "Allow Username Change",sername(type="text", placeholder="{{_ 'username'}}" value="{{currentSetting.mailServer.username}}")
// li.smtp-form
// .title {{_ 'smtp-password'}}
// .form-group
// input.wekan-form-control#mail-server-password(type="password", placeholder="{{_ 'password'}}" value="")
// li.smtp-form
// .title {{_ 'smtp-tls'}}
// .form-group
// a.flex.js-toggle-tls
// .materialCheckBox#mail-server-tls(class="{{#if currentSetting.mailServer.enableTLS}}is-checked{{/if}}")
//
// span {{_ 'smtp-tls-description'}}
//
// li.smtp-form
// .title {{_ 'send-from'}}
// .form-group
// input.wekan-form-control#mail-server-from(type="email", placeholder="no-reply@domain.com" value="{{currentSetting.mailServer.from}}")
//
// li
// button.js-save.primary {{_ 'save'}}
li
button.js-send-smtp-test-email.primary {{_ 'send-smtp-test'}}
template(name='tableVisibilityModeSettings')
ul#tableVisibilityMode-setting.setting-detail
li.tableVisibilityMode-form
.title {{_ 'tableVisibilityMode-allowPrivateOnly'}}
.form-group.flex
input.wekan-form-control#accounts-allowPrivateOnly(type="radio" name="allowPrivateOnly" value="true" checked="{{#if allowPrivateOnly}}checked{{/if}}")
label {{_ 'yes'}}
input.wekan-form-control#accounts-allowPrivateOnly(type="radio" name="allowPrivateOnly" value="false" checked="{{#unless allowPrivateOnly}}checked{{/unless}}")
label {{_ 'no'}}
button.js-tableVisibilityMode-save.primary {{_ 'save'}}
template(name='accountSettings')
ul#account-setting.setting-detail
li.accounts-form
.title {{_ 'accounts-allowEmailChange'}}
.form-group.flex
input.wekan-form-control#accounts-allowEmailChange(type="radio" name="allowEmailChange" value="true" checked="{{#if allowEmailChange}}checked{{/if}}")
label {{_ 'yes'}}
input.wekan-form-control#accounts-allowEmailChange(type="radio" name="allowEmailChange" value="false" checked="{{#unless allowEmailChange}}checked{{/unless}}")
label {{_ 'no'}}
.title {{_ 'accounts-allowUserNameChange'}}
.form-group.flex
input.wekan-form-control#accounts-allowUserNameChange(type="radio" name="allowUserNameChange" value="true" checked="{{#if allowUserNameChange}}checked{{/if}}")
label {{_ 'yes'}}
input.wekan-form-control#accounts-allowUserNameChange(type="radio" name="allowUserNameChange" value="false" checked="{{#unless allowUserNameChange}}checked{{/unless}}")
label {{_ 'no'}}
.title {{_ 'accounts-allowUserDelete'}}
.form-group.flex
input.wekan-form-control#accounts-allowUserDelete(type="radio" name="allowUserDelete" value="true" checked="{{#if allowUserDelete}}checked{{/if}}")
label {{_ 'yes'}}
input.wekan-form-control#accounts-allowUserDelete(type="radio" name="allowUserDelete" value="false" checked="{{#unless allowUserDelete}}checked{{/unless}}")
label {{_ 'no'}}
button.js-accounts-save.primary {{_ 'save'}}
// Brute force lockout settings moved to People/Locked Users section
template(name='announcementSettings')
ul#announcement-setting.setting-detail
li
a.flex.js-toggle-activemessage
.materialCheckBox(class="{{#if currentAnnouncements.enabled}}is-checked{{/if}}")
span {{_ 'admin-announcement-active'}}
li
.admin-announcement(class="{{#if currentAnnouncements.enabled}}{{else}}hide{{/if}}")
ul
li
.title {{_ 'admin-announcement-title'}}
textarea#admin-announcement.wekan-form-control= currentAnnouncements.body
li
button.js-announcement-save.primary {{_ 'save'}}
template(name='accessibilitySettings')
ul#accessibility-setting.setting-detail
li
a(href="/accessibility" style="text-decoration: underline; color: blue;") {{_ 'accessibility'}}
li
a.flex.js-toggle-accessibility
.materialCheckBox(class="{{#if currentAccessibility.enabled}}is-checked{{/if}}")
span {{_ 'accessibility-page-enabled'}}
li
.accessibility-content(class="{{#if currentAccessibility.enabled}}{{else}}hide{{/if}}")
ul
li
.title {{_ 'accessibility-title'}}
textarea#admin-accessibility-title.wekan-form-control= currentAccessibility.title
li
.title {{_ 'accessibility-content'}}
textarea#admin-accessibility-content.wekan-form-control= currentAccessibility.body
li
button.js-accessibility-save.primary {{_ 'save'}}
template(name='layoutSettings')
ul#layout-setting.setting-detail
li
button.js-all-boards-hide-activities.primary {{_ 'hide-activities-of-all-boards'}}
li.layout-form
.title {{_ 'oidc-button-text'}}
.form-group
input.wekan-form-control#oidcBtnTextvalue(type="text", placeholder="" value="{{currentSetting.oidcBtnText}}")
li.layout-form
.title {{_ 'can-invite-if-same-mailDomainName'}}
.form-group
input.wekan-form-control#mailDomainNamevalue(type="text", placeholder="" value="{{currentSetting.mailDomainName}}")
li.layout-form
.title {{_ 'custom-legal-notice-link-url'}}
.form-group
input.wekan-form-control#legalNoticevalue(type="text", placeholder="" value="{{currentSetting.legalNotice}}")
li.layout-form
.title {{_ 'display-authentication-method'}}
.form-group.flex
input.wekan-form-control#display-authentication-method(type="radio" name="displayAuthenticationMethod" value="true" checked="{{#if currentSetting.displayAuthenticationMethod}}checked{{/if}}")
label {{_ 'yes'}}
input.wekan-form-control#display-authentication-method(type="radio" name="displayAuthenticationMethod" value="false" checked="{{#unless currentSetting.displayAuthenticationMethod}}checked{{/unless}}")
label {{_ 'no'}}
li.layout-form
.title {{_ 'default-authentication-method'}}
+selectAuthenticationMethod(authenticationMethod=currentSetting.defaultAuthenticationMethod)
li.layout-form
.title {{_ 'wait-spinner'}}
+selectSpinnerName(spinnerName=currentSetting.spinnerName)
li.layout-form
.title {{_ 'custom-product-name'}}
.form-group
input.wekan-form-control#product-name(type="text", placeholder="" value="{{currentSetting.productName}}")
li.layout-form
.title {{_ 'hide-logo'}}
.form-group.flex
input.wekan-form-control#hide-logo(type="radio" name="hideLogo" value="true" checked="{{#if currentSetting.hideLogo}}checked{{/if}}")
label {{_ 'yes'}}
input.wekan-form-control#hide-logo(type="radio" name="hideLogo" value="false" checked="{{#unless currentSetting.hideLogo}}checked{{/unless}}")
label {{_ 'no'}}
li.layout-form
.title {{_ 'custom-login-logo-image-url'}}
.form-group
input.wekan-form-control#custom-login-logo-image-url(type="text", placeholder="" value="{{currentSetting.customLoginLogoImageUrl}}")
li.layout-form
.title {{_ 'custom-login-logo-link-url'}}
.form-group
input.wekan-form-control#custom-login-logo-link-url(type="text", placeholder="" value="{{currentSetting.customLoginLogoLinkUrl}}")
li.layout-form
.title {{_ 'custom-help-link-url'}}
.form-group
input.wekan-form-control#custom-help-link-url(type="text", placeholder="" value="{{currentSetting.customHelpLinkUrl}}")
li.layout-form
.title {{_ 'text-below-custom-login-logo'}}
.form-group
textarea#text-below-custom-login-logo.wekan-form-control= currentSetting.textBelowCustomLoginLogo
li.layout-form
.title {{_ 'custom-top-left-corner-logo-image-url'}}
.form-group
input.wekan-form-control#custom-top-left-corner-logo-image-url(type="text", placeholder="" value="{{currentSetting.customTopLeftCornerLogoImageUrl}}")
li.layout-form
.title {{_ 'custom-top-left-corner-logo-link-url'}}
.form-group
input.wekan-form-control#custom-top-left-corner-logo-link-url(type="text", placeholder="" value="{{currentSetting.customTopLeftCornerLogoLinkUrl}}")
li.layout-form
.title {{_ 'custom-top-left-corner-logo-height'}}
.form-group
input.wekan-form-control#custom-top-left-corner-logo-height(type="text", placeholder="" value="{{currentSetting.customTopLeftCornerLogoHeight}}")
li.layout-form
.title {{_ 'automatic-linked-url-schemes'}}
.form-group
textarea#automatic-linked-url-schemes.wekan-form-control= currentSetting.automaticLinkedUrlSchemes
li.layout-form
.title {{_ 'hide-card-counter-list'}}
.form-group.flex
input.wekan-form-control#hide-card-counter-list(type="radio" name="hideCardCounterList" value="true" checked="{{#if currentSetting.hideCardCounterList}}checked{{/if}}")
label {{_ 'yes'}}
input.wekan-form-control#hide-card-counter-list(type="radio" name="hideCardCounterList" value="false" checked="{{#unless currentSetting.hideCardCounterList}}checked{{/unless}}")
label {{_ 'no'}}
li.layout-form
.title {{_ 'hide-board-member-list'}}
.form-group.flex
input.wekan-form-control#hide-board-member-list(type="radio" name="hideBoardMemberList" value="true" checked="{{#if currentSetting.hideBoardMemberList}}checked{{/if}}")
label {{_ 'yes'}}
input.wekan-form-control#hide-board-member-list(type="radio" name="hideBoardMemberList" value="false" checked="{{#unless currentSetting.hideBoardMemberList}}checked{{/unless}}")
label {{_ 'no'}}
li
button.js-save-layout.primary {{_ 'save'}}
template(name='selectAuthenticationMethod')
select#defaultAuthenticationMethod
each authentications
if isSelected value
option(value="{{value}}" selected) {{_ value}}
else
option(value="{{value}}") {{_ value}}
template(name='selectSpinnerName')
select#spinnerName
each spinner in spinners
if isSelected spinner
option(value="{{spinner}}" selected) {{_ spinner}}
else
option(value="{{spinner}}") {{_ spinner}}