🎨 Add a 'Remember me' checkbox when logging in to save a session https://github.com/siyuan-note/siyuan/pull/14964

This commit is contained in:
Daniel 2025-06-04 15:54:31 +08:00
parent aa35dd827b
commit f3fe90cbd8
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
13 changed files with 37 additions and 33 deletions

View file

@ -1596,6 +1596,7 @@
"253": "جارٍ ضغط الملف [%s]، يرجى الانتظار...", "253": "جارٍ ضغط الملف [%s]، يرجى الانتظار...",
"254": "[Region ID] معرّف المنطقة غير صحيح، يرجى الرجوع إلى وثائق مزود خدمة S3 لتكوين معرّف المنطقة", "254": "[Region ID] معرّف المنطقة غير صحيح، يرجى الرجوع إلى وثائق مزود خدمة S3 لتكوين معرّف المنطقة",
"255": "قام الموقع المستهدف بتمكين حماية الروابط المباشرة، لذلك لا يمكن تنزيل [%d] من الموارد", "255": "قام الموقع المستهدف بتمكين حماية الروابط المباشرة، لذلك لا يمكن تنزيل [%d] من الموارد",
"256": "المسار المحدد [%s] يحتوي على مسار مساحة عمل رئيسي [%s]" "256": "المسار المحدد [%s] يحتوي على مسار مساحة عمل رئيسي [%s]",
"257": "تذكرني لمدة 30 يومًا"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "Datei [%s] wird komprimiert, bitte warten...", "253": "Datei [%s] wird komprimiert, bitte warten...",
"254": "[Region ID] Falsche Regions-ID, bitte konsultieren Sie die Dokumentation des S3-Dienstanbieters zur Konfiguration der Regions-ID", "254": "[Region ID] Falsche Regions-ID, bitte konsultieren Sie die Dokumentation des S3-Dienstanbieters zur Konfiguration der Regions-ID",
"255": "Die Zielseite hat den Hotlink-Schutz aktiviert, daher ist es nicht möglich, [%d] Ressourcen herunterzuladen", "255": "Die Zielseite hat den Hotlink-Schutz aktiviert, daher ist es nicht möglich, [%d] Ressourcen herunterzuladen",
"256": "Der angegebene Pfad [%s] hat einen übergeordneten Arbeitsbereichspfad [%s]" "256": "Der angegebene Pfad [%s] hat einen übergeordneten Arbeitsbereichspfad [%s]",
"257": "Erinnere dich 30 Tage an mich"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "Comprimiendo el archivo [%s], por favor espere...", "253": "Comprimiendo el archivo [%s], por favor espere...",
"254": "[Region ID] ID de región incorrecto, por favor consulte la documentación del proveedor de servicios S3 para configurar el ID de región", "254": "[Region ID] ID de región incorrecto, por favor consulte la documentación del proveedor de servicios S3 para configurar el ID de región",
"255": "El sitio de destino ha activado la protección contra hotlinking, por lo que no es posible descargar [%d] recursos", "255": "El sitio de destino ha activado la protección contra hotlinking, por lo que no es posible descargar [%d] recursos",
"256": "La ruta especificada [%s] tiene una ruta de espacio de trabajo padre [%s]" "256": "La ruta especificada [%s] tiene una ruta de espacio de trabajo padre [%s]",
"257": "Recuérdame durante 30 días"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "Compression du fichier [%s], veuillez patienter...", "253": "Compression du fichier [%s], veuillez patienter...",
"254": "[Region ID] ID de région incorrect, veuillez consulter la documentation du fournisseur de services S3 pour configurer l'ID de région", "254": "[Region ID] ID de région incorrect, veuillez consulter la documentation du fournisseur de services S3 pour configurer l'ID de région",
"255": "Le site cible a activé la protection contre le hotlinking, il est donc impossible de télécharger [%d] ressources", "255": "Le site cible a activé la protection contre le hotlinking, il est donc impossible de télécharger [%d] ressources",
"256": "Le chemin spécifié [%s] contient un chemin d'espace de travail parent [%s]" "256": "Le chemin spécifié [%s] contient un chemin d'espace de travail parent [%s]",
"257": "Souviens-toi de moi pendant 30 jours"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "דוחס את הקובץ [%s], אנא המתן...", "253": "דוחס את הקובץ [%s], אנא המתן...",
"254": "[Region ID] מזהה האזור שגוי, אנא עיין בתיעוד ספק שירותי S3 כדי להגדיר את מזהה האזור", "254": "[Region ID] מזהה האזור שגוי, אנא עיין בתיעוד ספק שירותי S3 כדי להגדיר את מזהה האזור",
"255": "האתר היעד הפעיל הגנה על קישורים חמים, ולכן לא ניתן להוריד [%d] משאבים", "255": "האתר היעד הפעיל הגנה על קישורים חמים, ולכן לא ניתן להוריד [%d] משאבים",
"256": "הנתיב שצוין [%s] מכיל נתיב מרחב עבודה אב [%s]" "256": "הנתיב שצוין [%s] מכיל נתיב מרחב עבודה אב [%s]",
"257": "זכור אותי למשך 30 יום"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "Compressione del file [%s], attendere prego...", "253": "Compressione del file [%s], attendere prego...",
"254": "[Region ID] ID regione non corretto, si prega di consultare la documentazione del fornitore di servizi S3 per configurare l'ID regione", "254": "[Region ID] ID regione non corretto, si prega di consultare la documentazione del fornitore di servizi S3 per configurare l'ID regione",
"255": "Il sito di destinazione ha abilitato la protezione hotlink, quindi non è possibile scaricare [%d] risorse", "255": "Il sito di destinazione ha abilitato la protezione hotlink, quindi non è possibile scaricare [%d] risorse",
"256": "Il percorso specificato [%s] ha un percorso di spazio di lavoro padre [%s]" "256": "Il percorso specificato [%s] ha un percorso di spazio di lavoro padre [%s]",
"257": "Ricordati di me per 30 giorni"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "ファイル [%s] を圧縮しています、お待ちください...", "253": "ファイル [%s] を圧縮しています、お待ちください...",
"254": "[Region ID] リージョンIDが正しくありません。S3サービスプロバイダーのドキュメントを参照してリージョンIDを設定してください", "254": "[Region ID] リージョンIDが正しくありません。S3サービスプロバイダーのドキュメントを参照してリージョンIDを設定してください",
"255": "ターゲットサイトはホットリンク保護を有効にしているため、[%d] 個のリソースをダウンロードできません", "255": "ターゲットサイトはホットリンク保護を有効にしているため、[%d] 個のリソースをダウンロードできません",
"256": "指定されたパス [%s] の親にワークスペースパス [%s] が存在します" "256": "指定されたパス [%s] の親にワークスペースパス [%s] が存在します",
"257": "30日間私を覚えていてください"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "Kompresja pliku [%s], proszę czekać...", "253": "Kompresja pliku [%s], proszę czekać...",
"254": "[Region ID] Nieprawidłowy identyfikator regionu, proszę zapoznać się z dokumentacją dostawcy usług S3 w celu skonfigurowania identyfikatora regionu", "254": "[Region ID] Nieprawidłowy identyfikator regionu, proszę zapoznać się z dokumentacją dostawcy usług S3 w celu skonfigurowania identyfikatora regionu",
"255": "Docelowa strona włączyła ochronę przed hotlinkowaniem, [%d] zasobów nie można pobrać", "255": "Docelowa strona włączyła ochronę przed hotlinkowaniem, [%d] zasobów nie można pobrać",
"256": "Określona ścieżka [%s] ma nadrzędną ścieżkę przestrzeni roboczej [%s]" "256": "Określona ścieżka [%s] ma nadrzędną ścieżkę przestrzeni roboczej [%s]",
"257": "Zapamiętaj mnie na 30 dni"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "Сжатие файла [%s], пожалуйста, подождите...", "253": "Сжатие файла [%s], пожалуйста, подождите...",
"254": "[Region ID] Неправильный идентификатор региона, пожалуйста, обратитесь к документации поставщика услуг S3 для настройки идентификатора региона", "254": "[Region ID] Неправильный идентификатор региона, пожалуйста, обратитесь к документации поставщика услуг S3 для настройки идентификатора региона",
"255": "Целевой сайт включил защиту от хотлинков, [%d] ресурсов невозможно скачать", "255": "Целевой сайт включил защиту от хотлинков, [%d] ресурсов невозможно скачать",
"256": "Указанный путь [%s] имеет родительский путь рабочей области [%s]" "256": "Указанный путь [%s] имеет родительский путь рабочей области [%s]",
"257": "Запомнить меня на 30 дней"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "正在壓縮文件 [%s],請稍等...", "253": "正在壓縮文件 [%s],請稍等...",
"254": "[Region ID] 不正確,請參考 S3 服務提供商的文檔配置地域 ID", "254": "[Region ID] 不正確,請參考 S3 服務提供商的文檔配置地域 ID",
"255": "目標站點啟用了防盜鏈,[%d] 個資源無法下載", "255": "目標站點啟用了防盜鏈,[%d] 個資源無法下載",
"256": "指定的路徑 [%s] 父級存在工作空間路徑 [%s]" "256": "指定的路徑 [%s] 父級存在工作空間路徑 [%s]",
"257": "記住我 30 天"
} }
} }

View file

@ -1596,6 +1596,7 @@
"253": "正在压缩文件 [%s],请稍等...", "253": "正在压缩文件 [%s],请稍等...",
"254": "[Region ID] 不正确,请参考 S3 服务提供商的文档配置地域 ID", "254": "[Region ID] 不正确,请参考 S3 服务提供商的文档配置地域 ID",
"255": "目标站点启用了防盗链,[%d] 个资源无法下载", "255": "目标站点启用了防盗链,[%d] 个资源无法下载",
"256": "指定的路径 [%s] 父级存在工作空间路径 [%s]" "256": "指定的路径 [%s] 父级存在工作空间路径 [%s]",
"257": "记住我 30 天"
} }
} }

View file

@ -184,7 +184,7 @@
<img id="captchaImg" style="top: 1px;position: absolute;height: 26px;right: 1px;cursor: pointer"> <img id="captchaImg" style="top: 1px;position: absolute;height: 26px;right: 1px;cursor: pointer">
<input id="captcha" class="b3-text-field" placeholder="{{.l3}}"> <input id="captcha" class="b3-text-field" placeholder="{{.l3}}">
</div> </div>
<div style="width: 240px; margin: 8px auto; text-align: left;"> <div style="width: 240px; margin: 8px auto; text-align: left; display: flex; align-items: center;">
<input type="checkbox" id="rememberMe" style="margin-right: 8px;"> <input type="checkbox" id="rememberMe" style="margin-right: 8px;">
<label for="rememberMe" style="color: var(--b3-theme-on-surface); font-size: 14px;">{{.l10}}</label> <label for="rememberMe" style="color: var(--b3-theme-on-surface); font-size: 14px;">{{.l10}}</label>
</div> </div>

View file

@ -27,11 +27,11 @@ import (
"time" "time"
"github.com/88250/gulu" "github.com/88250/gulu"
ginSessions "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/siyuan-note/logging" "github.com/siyuan-note/logging"
"github.com/siyuan-note/siyuan/kernel/util" "github.com/siyuan-note/siyuan/kernel/util"
ginSessions "github.com/gin-contrib/sessions"
"github.com/steambap/captcha" "github.com/steambap/captcha"
) )
@ -122,27 +122,20 @@ func LoginAuth(c *gin.Context) {
workspaceSession.AccessAuthCode = authCode workspaceSession.AccessAuthCode = authCode
util.WrongAuthCount = 0 util.WrongAuthCount = 0
workspaceSession.Captcha = gulu.Rand.String(7) workspaceSession.Captcha = gulu.Rand.String(7)
// Handle remember me preference
if rememberMe, ok := arg["rememberMe"].(bool); ok && rememberMe {
// Set session cookie to expire in 30 days
ginSessions.Default(c).Options(ginSessions.Options{
Path: "/",
Secure: util.SSL,
MaxAge: 30 * 24 * 60 * 60, // 30 days in seconds
HttpOnly: true,
})
} else {
// Default session expiration (browser session)
ginSessions.Default(c).Options(ginSessions.Options{
Path: "/",
Secure: util.SSL,
MaxAge: 0, // Session cookie
HttpOnly: true,
})
}
logging.LogInfof("auth success [ip=%s]", util.GetRemoteAddr(c.Request)) maxAge := 0 // Default session expiration (browser session)
if rememberMe, ok := arg["rememberMe"].(bool); ok && rememberMe {
// Add a 'Remember me' checkbox when logging in to save a session https://github.com/siyuan-note/siyuan/pull/14964
maxAge = 60 * 60 * 24 * 30 // 30 days
}
ginSessions.Default(c).Options(ginSessions.Options{
Path: "/",
Secure: util.SSL,
MaxAge: maxAge,
HttpOnly: true,
})
logging.LogInfof("auth success [ip=%s, maxAge=%d]", util.GetRemoteAddr(c.Request), maxAge)
if err := session.Save(c); err != nil { if err := session.Save(c); err != nil {
logging.LogErrorf("save session failed: " + err.Error()) logging.LogErrorf("save session failed: " + err.Error())
c.Status(http.StatusInternalServerError) c.Status(http.StatusInternalServerError)