mirror of
https://github.com/h44z/wg-portal.git
synced 2025-06-28 01:07:03 +00:00
allow to hide login form (#459)
use the `hide_login_form` parameter in the `auth` settings to configure this feature
This commit is contained in:
parent
f994700caf
commit
dab19a123e
@ -76,6 +76,7 @@ auth:
|
|||||||
webauthn:
|
webauthn:
|
||||||
enabled: true
|
enabled: true
|
||||||
min_password_length: 16
|
min_password_length: 16
|
||||||
|
hide_login_form: false
|
||||||
|
|
||||||
web:
|
web:
|
||||||
listening_address: :8888
|
listening_address: :8888
|
||||||
@ -354,6 +355,12 @@ Some core authentication options are shared across all providers, while others a
|
|||||||
The default admin password strength is also enforced by this setting.
|
The default admin password strength is also enforced by this setting.
|
||||||
- **Important:** The password should be strong and secure. It is recommended to use a password with at least 16 characters, including uppercase and lowercase letters, numbers, and special characters.
|
- **Important:** The password should be strong and secure. It is recommended to use a password with at least 16 characters, including uppercase and lowercase letters, numbers, and special characters.
|
||||||
|
|
||||||
|
### `hide_login_form`
|
||||||
|
- **Default:** `false`
|
||||||
|
- **Description:** If `true`, the login form is hidden and only the OIDC, OAuth, LDAP, or WebAuthn providers are shown. This is useful if you want to enforce a specific authentication method.
|
||||||
|
If no social login providers are configured, the login form is always shown, regardless of this setting.
|
||||||
|
- **Important:** You can still access the login form by adding the `?all` query parameter to the login URL (e.g. https://wg.portal/#/login?all).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### OIDC
|
### OIDC
|
||||||
|
@ -16,7 +16,10 @@ const password = ref("")
|
|||||||
const usernameInvalid = computed(() => username.value === "")
|
const usernameInvalid = computed(() => username.value === "")
|
||||||
const passwordInvalid = computed(() => password.value === "")
|
const passwordInvalid = computed(() => password.value === "")
|
||||||
const disableLoginBtn = computed(() => username.value === "" || password.value === "" || loggingIn.value)
|
const disableLoginBtn = computed(() => username.value === "" || password.value === "" || loggingIn.value)
|
||||||
|
const showLoginForm = computed(() => {
|
||||||
|
console.log(router.currentRoute.value.query)
|
||||||
|
return settings.Setting('LoginFormVisible') || router.currentRoute.value.query.hasOwnProperty('all');
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await settings.LoadSettings()
|
await settings.LoadSettings()
|
||||||
@ -98,7 +101,7 @@ const externalLogin = function (provider) {
|
|||||||
</div></div>
|
</div></div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<fieldset>
|
<fieldset v-if="showLoginForm">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label" for="inputUsername">{{ $t('login.username.label') }}</label>
|
<label class="form-label" for="inputUsername">{{ $t('login.username.label') }}</label>
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
@ -118,19 +121,40 @@ const externalLogin = function (provider) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mt-5 mb-2">
|
<div class="row mt-5 mb-2">
|
||||||
<div class="col-lg-4">
|
<div class="col-sm-4 col-xs-12">
|
||||||
<button :disabled="disableLoginBtn" class="btn btn-primary" type="submit" @click.prevent="login">
|
<button :disabled="disableLoginBtn" class="btn btn-primary mb-2" type="submit" @click.prevent="login">
|
||||||
{{ $t('login.button') }} <div v-if="loggingIn" class="d-inline"><i class="ms-2 fa-solid fa-circle-notch fa-spin"></i></div>
|
{{ $t('login.button') }} <div v-if="loggingIn" class="d-inline"><i class="ms-2 fa-solid fa-circle-notch fa-spin"></i></div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-8 mb-2 text-end">
|
<div class="col-sm-8 col-xs-12 text-sm-end">
|
||||||
<button v-if="settings.Setting('WebAuthnEnabled')" class="btn btn-primary" type="submit" @click.prevent="loginWebAuthn">
|
<button v-if="settings.Setting('WebAuthnEnabled')" class="btn btn-primary" type="submit" @click.prevent="loginWebAuthn">
|
||||||
{{ $t('login.button-webauthn') }} <div v-if="loggingIn" class="d-inline"><i class="ms-2 fa-solid fa-circle-notch fa-spin"></i></div>
|
{{ $t('login.button-webauthn') }} <div v-if="loggingIn" class="d-inline"><i class="ms-2 fa-solid fa-circle-notch fa-spin"></i></div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mt-5 d-flex">
|
<div class="row mt-4 d-flex">
|
||||||
|
<div class="col-lg-12 d-flex mb-2">
|
||||||
|
<!-- OpenIdConnect / OAUTH providers -->
|
||||||
|
<button v-for="(provider, idx) in auth.LoginProviders" :key="provider.Identifier" :class="{'ms-1':idx > 0}"
|
||||||
|
:disabled="loggingIn" :title="provider.Name" class="btn btn-outline-primary flex-fill"
|
||||||
|
v-html="provider.Name" @click.prevent="externalLogin(provider)"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset v-else>
|
||||||
|
<div class="row mt-1 mb-2" v-if="settings.Setting('WebAuthnEnabled')">
|
||||||
|
<div class="col-lg-12 d-flex mb-2">
|
||||||
|
<button class="btn btn-outline-primary flex-fill" type="submit" @click.prevent="loginWebAuthn">
|
||||||
|
{{ $t('login.button-webauthn') }} <div v-if="loggingIn" class="d-inline"><i class="ms-2 fa-solid fa-circle-notch fa-spin"></i></div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-1 d-flex">
|
||||||
<div class="col-lg-12 d-flex mb-2">
|
<div class="col-lg-12 d-flex mb-2">
|
||||||
<!-- OpenIdConnect / OAUTH providers -->
|
<!-- OpenIdConnect / OAUTH providers -->
|
||||||
<button v-for="(provider, idx) in auth.LoginProviders" :key="provider.Identifier" :class="{'ms-1':idx > 0}"
|
<button v-for="(provider, idx) in auth.LoginProviders" :key="provider.Identifier" :class="{'ms-1':idx > 0}"
|
||||||
@ -144,7 +168,6 @@ const externalLogin = function (provider) {
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2231,6 +2231,9 @@
|
|||||||
"ApiAdminOnly": {
|
"ApiAdminOnly": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"LoginFormVisible": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"MailLinkOnly": {
|
"MailLinkOnly": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
@ -381,6 +381,8 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
ApiAdminOnly:
|
ApiAdminOnly:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
LoginFormVisible:
|
||||||
|
type: boolean
|
||||||
MailLinkOnly:
|
MailLinkOnly:
|
||||||
type: boolean
|
type: boolean
|
||||||
MinPasswordLength:
|
MinPasswordLength:
|
||||||
|
@ -96,10 +96,13 @@ func (e ConfigEndpoint) handleSettingsGet() http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
sessionUser := domain.GetUserInfo(r.Context())
|
sessionUser := domain.GetUserInfo(r.Context())
|
||||||
|
|
||||||
|
hasSocialLogin := len(e.cfg.Auth.OAuth) > 0 || len(e.cfg.Auth.OpenIDConnect) > 0 || e.cfg.Auth.WebAuthn.Enabled
|
||||||
|
|
||||||
// For anonymous users, we return the settings object with minimal information
|
// For anonymous users, we return the settings object with minimal information
|
||||||
if sessionUser.Id == domain.CtxUnknownUserId || sessionUser.Id == "" {
|
if sessionUser.Id == domain.CtxUnknownUserId || sessionUser.Id == "" {
|
||||||
respond.JSON(w, http.StatusOK, model.Settings{
|
respond.JSON(w, http.StatusOK, model.Settings{
|
||||||
WebAuthnEnabled: e.cfg.Auth.WebAuthn.Enabled,
|
WebAuthnEnabled: e.cfg.Auth.WebAuthn.Enabled,
|
||||||
|
LoginFormVisible: !e.cfg.Auth.HideLoginForm || !hasSocialLogin,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
respond.JSON(w, http.StatusOK, model.Settings{
|
respond.JSON(w, http.StatusOK, model.Settings{
|
||||||
@ -109,6 +112,7 @@ func (e ConfigEndpoint) handleSettingsGet() http.HandlerFunc {
|
|||||||
ApiAdminOnly: e.cfg.Advanced.ApiAdminOnly,
|
ApiAdminOnly: e.cfg.Advanced.ApiAdminOnly,
|
||||||
WebAuthnEnabled: e.cfg.Auth.WebAuthn.Enabled,
|
WebAuthnEnabled: e.cfg.Auth.WebAuthn.Enabled,
|
||||||
MinPasswordLength: e.cfg.Auth.MinPasswordLength,
|
MinPasswordLength: e.cfg.Auth.MinPasswordLength,
|
||||||
|
LoginFormVisible: !e.cfg.Auth.HideLoginForm || !hasSocialLogin,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,4 +12,5 @@ type Settings struct {
|
|||||||
ApiAdminOnly bool `json:"ApiAdminOnly"`
|
ApiAdminOnly bool `json:"ApiAdminOnly"`
|
||||||
WebAuthnEnabled bool `json:"WebAuthnEnabled"`
|
WebAuthnEnabled bool `json:"WebAuthnEnabled"`
|
||||||
MinPasswordLength int `json:"MinPasswordLength"`
|
MinPasswordLength int `json:"MinPasswordLength"`
|
||||||
|
LoginFormVisible bool `json:"LoginFormVisible"`
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ type Auth struct {
|
|||||||
// MinPasswordLength is the minimum password length for user accounts. This also applies to the admin user.
|
// MinPasswordLength is the minimum password length for user accounts. This also applies to the admin user.
|
||||||
// It is encouraged to set this value to at least 16 characters.
|
// It is encouraged to set this value to at least 16 characters.
|
||||||
MinPasswordLength int `yaml:"min_password_length"`
|
MinPasswordLength int `yaml:"min_password_length"`
|
||||||
|
// HideLoginForm specifies whether the login form should be hidden. If no social login providers are configured,
|
||||||
|
// the login form will be shown regardless of this setting.
|
||||||
|
HideLoginForm bool `yaml:"hide_login_form"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// BaseFields contains the basic fields that are used to map user information from the authentication providers.
|
// BaseFields contains the basic fields that are used to map user information from the authentication providers.
|
||||||
|
@ -95,6 +95,9 @@ func (c *Config) LogStartupValues() {
|
|||||||
"oidcProviders", len(c.Auth.OpenIDConnect),
|
"oidcProviders", len(c.Auth.OpenIDConnect),
|
||||||
"oauthProviders", len(c.Auth.OAuth),
|
"oauthProviders", len(c.Auth.OAuth),
|
||||||
"ldapProviders", len(c.Auth.Ldap),
|
"ldapProviders", len(c.Auth.Ldap),
|
||||||
|
"webauthnEnabled", c.Auth.WebAuthn.Enabled,
|
||||||
|
"minPasswordLength", c.Auth.MinPasswordLength,
|
||||||
|
"hideLoginForm", c.Auth.HideLoginForm,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +172,7 @@ func defaultConfig() *Config {
|
|||||||
|
|
||||||
cfg.Auth.WebAuthn.Enabled = true
|
cfg.Auth.WebAuthn.Enabled = true
|
||||||
cfg.Auth.MinPasswordLength = 16
|
cfg.Auth.MinPasswordLength = 16
|
||||||
|
cfg.Auth.HideLoginForm = false
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user