feat: add auto login to skip sign-in method chooser

If you combine OIDC with local accounts or if your OIDC provider is an
external company (Facebook, GitHub, …) it makes sense for HedgeDoc to
show a additional login modal so users know that they will leave the
page.

However, if OAuth2/OIDC is a deployment's primary sign-in method and a
local OIDC provider is being used, users expect the common SSO method
being used, and he "Choose method" modal is a redundant extra click.
Essentially, you may have to click login thrice:

- Click login -> modal opens
- Click Login with provider -> provider login opens
- Log in (unless you are logged in already)

This simple patch adds an auto-login configuration, which makes the Sign
In button link straight to the provider's OAuth2 flow, improving the UX
of tHedgeDoc's login.

Signed-off-by: Lars Kiesow <lkiesow@uos.de>
This commit is contained in:
Lars Kiesow
2026-07-10 23:29:16 +02:00
committed by Philip Molares
parent ed7f374434
commit d05cfe4e9f
3 changed files with 25 additions and 2 deletions

9
app.js
View File

@@ -253,6 +253,15 @@ app.locals.authProviders = {
allowEmailRegister: config.allowEmailRegister allowEmailRegister: config.allowEmailRegister
} }
// If none of the form-based methods (LDAP, Email, OpenID) are configured and
// exactly one redirect-style external provider is, skip the "Choose method"
// dialog and link "Sign In" straight to that provider's login page.
const externalProviderKeys = ['facebook', 'twitter', 'github', 'gitlab', 'mattermost', 'dropbox', 'google', 'saml', 'oauth2']
const enabledExternalProviders = externalProviderKeys.filter((key) => app.locals.authProviders[key])
app.locals.authProviders.autoLoginProvider = (!app.locals.authProviders.ldap && !app.locals.authProviders.email && !app.locals.authProviders.openID && enabledExternalProviders.length === 1)
? enabledExternalProviders[0]
: null
// Export/Import menu items // Export/Import menu items
app.locals.enableDropBoxSave = config.isDropboxEnable app.locals.enableDropBoxSave = config.isDropboxEnable
app.locals.enableGitHubGist = config.isGitHubEnable app.locals.enableGitHubGist = config.isGitHubEnable

View File

@@ -1,5 +1,11 @@
# Release Notes # Release Notes
## <i class="fa fa-tag"></i> 1.x.x <i class="fa fa-calendar-o"></i> UNRELEASED
### Enhancements
- Automatically skip the login modal if no form-based login and exactly one external login provider is configured
## <i class="fa fa-tag"></i> 1.11.1 <i class="fa fa-calendar-o"></i> 2026-07-24 ## <i class="fa fa-tag"></i> 1.11.1 <i class="fa fa-calendar-o"></i> 2026-07-24
### Security fixes ### Security fixes

View File

@@ -15,7 +15,9 @@
<% if (allowAnonymous && !disableNoteCreation) { %> <% if (allowAnonymous && !disableNoteCreation) { %>
<a type="button" href="<%- serverURL %>/new" class="btn btn-sm btn-primary"><i class="fa fa-plus"></i> <%= __('New guest note') %></a> <a type="button" href="<%- serverURL %>/new" class="btn btn-sm btn-primary"><i class="fa fa-plus"></i> <%= __('New guest note') %></a>
<% } %> <% } %>
<% if (authProviders.facebook || authProviders.twitter || authProviders.github || authProviders.gitlab || authProviders.mattermost || authProviders.dropbox || authProviders.google || authProviders.ldap || authProviders.saml || authProviders.oauth2 || authProviders.email) { %> <% if (authProviders.autoLoginProvider) { %>
<a type="button" href="<%- serverURL %>/auth/<%- authProviders.autoLoginProvider %>" class="btn btn-sm btn-success ui-signin"><%= __('Sign In') %></a>
<% } else if (authProviders.facebook || authProviders.twitter || authProviders.github || authProviders.gitlab || authProviders.mattermost || authProviders.dropbox || authProviders.google || authProviders.ldap || authProviders.saml || authProviders.oauth2 || authProviders.email) { %>
<button class="btn btn-sm btn-success ui-signin" data-toggle="modal" data-target=".signin-modal"><%= __('Sign In') %></button> <button class="btn btn-sm btn-success ui-signin" data-toggle="modal" data-target=".signin-modal"><%= __('Sign In') %></button>
<% } %> <% } %>
</div> </div>
@@ -52,7 +54,13 @@
<% if (errorMessage && errorMessage.length > 0) { %> <% if (errorMessage && errorMessage.length > 0) { %>
<div class="alert alert-danger" style="max-width: 400px; margin: 0 auto;"><%= errorMessage %></div> <div class="alert alert-danger" style="max-width: 400px; margin: 0 auto;"><%= errorMessage %></div>
<% } %> <% } %>
<% if (authProviders.facebook || authProviders.twitter || authProviders.github || authProviders.gitlab || authProviders.mattermost || authProviders.dropbox || authProviders.google || authProviders.ldap || authProviders.saml || authProviders.oauth2 || authProviders.email) { %> <% if (authProviders.autoLoginProvider) { %>
<span class="ui-signin">
<br>
<a type="button" href="<%- serverURL %>/auth/<%- authProviders.autoLoginProvider %>" class="btn btn-lg btn-success ui-signin" style="min-width: 200px;"><%= __('Sign In') %></a>
</span>
<span class="ui-or"><%= __('or') %></span>
<% } else if (authProviders.facebook || authProviders.twitter || authProviders.github || authProviders.gitlab || authProviders.mattermost || authProviders.dropbox || authProviders.google || authProviders.ldap || authProviders.saml || authProviders.oauth2 || authProviders.email) { %>
<span class="ui-signin"> <span class="ui-signin">
<br> <br>
<a type="button" class="btn btn-lg btn-success ui-signin" data-toggle="modal" data-target=".signin-modal" style="min-width: 200px;"><%= __('Sign In') %></a> <a type="button" class="btn btn-lg btn-success ui-signin" data-toggle="modal" data-target=".signin-modal" style="min-width: 200px;"><%= __('Sign In') %></a>