added setting to turn off login/edits - LOGIN_AND_EDITS
This commit is contained in:
@@ -80,6 +80,7 @@ PATH = data/gobsidian.db
|
||||
REQUIRE_ADMIN_ACTIVATION = true
|
||||
REQUIRE_EMAIL_CONFIRMATION = false
|
||||
MFA_ENABLED_BY_DEFAULT = false
|
||||
LOGIN_AND_EDITS = true
|
||||
|
||||
[SECURITY]
|
||||
PWD_FAILURES_THRESHOLD = 5
|
||||
|
||||
@@ -45,6 +45,7 @@ type Config struct {
|
||||
RequireAdminActivation bool
|
||||
RequireEmailConfirmation bool
|
||||
MFAEnabledByDefault bool
|
||||
LoginAndEdits bool
|
||||
|
||||
// Security settings (failed-login thresholds and auto-ban config)
|
||||
PwdFailuresThreshold int
|
||||
@@ -92,6 +93,7 @@ var defaultConfig = map[string]map[string]string{
|
||||
"REQUIRE_ADMIN_ACTIVATION": "true",
|
||||
"REQUIRE_EMAIL_CONFIRMATION": "false",
|
||||
"MFA_ENABLED_BY_DEFAULT": "false",
|
||||
"LOGIN_AND_EDITS": "true",
|
||||
},
|
||||
"SECURITY": {
|
||||
"PWD_FAILURES_THRESHOLD": "5",
|
||||
@@ -219,6 +221,7 @@ func Load() (*Config, error) {
|
||||
config.RequireAdminActivation, _ = authSection.Key("REQUIRE_ADMIN_ACTIVATION").Bool()
|
||||
config.RequireEmailConfirmation, _ = authSection.Key("REQUIRE_EMAIL_CONFIRMATION").Bool()
|
||||
config.MFAEnabledByDefault, _ = authSection.Key("MFA_ENABLED_BY_DEFAULT").Bool()
|
||||
config.LoginAndEdits, _ = authSection.Key("LOGIN_AND_EDITS").Bool()
|
||||
|
||||
// Load SECURITY section
|
||||
secSection := cfg.Section("SECURITY")
|
||||
@@ -395,6 +398,8 @@ func (c *Config) SaveSetting(section, key, value string) error {
|
||||
c.RequireEmailConfirmation = value == "true"
|
||||
case "MFA_ENABLED_BY_DEFAULT":
|
||||
c.MFAEnabledByDefault = value == "true"
|
||||
case "LOGIN_AND_EDITS":
|
||||
c.LoginAndEdits = value == "true"
|
||||
}
|
||||
case "SECURITY":
|
||||
switch key {
|
||||
|
||||
@@ -972,6 +972,7 @@ func (h *Handlers) IndexHandler(c *gin.Context) {
|
||||
"breadcrumbs": utils.GenerateBreadcrumbs(""),
|
||||
"allowed_image_extensions": h.config.AllowedImageExtensions,
|
||||
"allowed_file_extensions": h.config.AllowedFileExtensions,
|
||||
"LoginAndEdits": h.config.LoginAndEdits,
|
||||
"Authenticated": isAuthenticated(c),
|
||||
"IsAdmin": isAdmin(c),
|
||||
"ContentTemplate": "folder_content",
|
||||
|
||||
@@ -13,6 +13,18 @@ import (
|
||||
|
||||
const csrfSessionKey = "csrf_token"
|
||||
|
||||
// RequireLoginAndEdits blocks access if LoginAndEdits setting is false.
|
||||
func (s *Server) RequireLoginAndEdits() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if !s.config.LoginAndEdits {
|
||||
c.Redirect(http.StatusFound, s.config.URLPrefix+"/?error=not_found")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) randomToken(n int) (string, error) {
|
||||
b := make([]byte, n)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
|
||||
@@ -105,15 +105,15 @@ func (s *Server) setupRoutes() {
|
||||
r.GET("/view_text/*path", h.ViewTextHandler)
|
||||
|
||||
// Auth routes
|
||||
r.GET("/editor/login", h.LoginPage)
|
||||
r.POST("/editor/login", s.CSRFRequire(), h.LoginPost)
|
||||
r.GET("/editor/login", s.RequireLoginAndEdits(), h.LoginPage)
|
||||
r.POST("/editor/login", s.RequireLoginAndEdits(), s.CSRFRequire(), h.LoginPost)
|
||||
r.POST("/editor/logout", s.RequireAuth(), s.CSRFRequire(), h.LogoutPost)
|
||||
// MFA challenge routes (no auth yet, but CSRF)
|
||||
r.GET("/editor/mfa", s.CSRFRequire(), h.MFALoginPage)
|
||||
r.POST("/editor/mfa", s.CSRFRequire(), h.MFALoginVerify)
|
||||
r.GET("/editor/mfa", s.RequireLoginAndEdits(), s.CSRFRequire(), h.MFALoginPage)
|
||||
r.POST("/editor/mfa", s.RequireLoginAndEdits(), s.CSRFRequire(), h.MFALoginVerify)
|
||||
|
||||
// New /editor group protected by auth + CSRF
|
||||
editor := r.Group("/editor", s.RequireAuth(), s.CSRFRequire())
|
||||
// New /editor group protected by auth + CSRF + LoginAndEdits
|
||||
editor := r.Group("/editor", s.RequireLoginAndEdits(), s.RequireAuth(), s.CSRFRequire())
|
||||
{
|
||||
editor.GET("/create", h.CreateNotePageHandler)
|
||||
editor.POST("/create", h.CreateNoteHandler)
|
||||
|
||||
@@ -308,9 +308,11 @@
|
||||
<i class="fas fa-right-from-bracket"></i>
|
||||
</button>
|
||||
{{else}}
|
||||
{{if .LoginAndEdits}}
|
||||
<a href="{{url "/editor/login"}}" class="text-gray-400 hover:text-white transition-colors" title="Login">
|
||||
<i class="fas fa-right-to-bracket"></i>
|
||||
</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
<button id="sidebar-toggle" class="toggle-btn" title="Toggle sidebar" aria-label="Toggle sidebar">
|
||||
@@ -582,6 +584,12 @@
|
||||
const collapsed = localStorage.getItem('sidebarCollapsed') === 'true';
|
||||
applySidebarState(collapsed);
|
||||
|
||||
// Check for error in query params
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.get('error') === 'not_found') {
|
||||
showNotification('The page does not exist', 'error', 5000);
|
||||
}
|
||||
|
||||
// Wire toggle button
|
||||
const toggleBtn = document.getElementById('sidebar-toggle');
|
||||
if (toggleBtn) {
|
||||
|
||||
Reference in New Issue
Block a user