74fa759274
- 安全: 认证改随机token会话(弃固定cookie), 笔记密码SHA256升级为bcrypt(自动迁移), 堵住GET /api/notes/:id泄露带密码笔记, CORS收紧+SameSite防CSRF, 上传图片内容嗅探 - 回收站: 软删除(deleted_at), 列表/恢复/彻底删除/清空, 目录子树连删连恢复 - 版本历史: note_versions表存快照, 每次保存自动留档, 支持查看/回滚 - 分享: 生成随机token分享链接, 支持过期时间, 公开阅读页share.html - 批量导出: 全部笔记打包zip(按目录结构+front matter) - 前端: 深色模式, Mermaid图表, 待办清单checkbox, 字数统计; 后台新增回收站/历史/分享面板和批量导出按钮 - 新增deploy/note-manager.service systemd单元与smoke_test.py
94 lines
2.1 KiB
Go
94 lines
2.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"note-manager/config"
|
|
"note-manager/middleware"
|
|
"note-manager/service"
|
|
)
|
|
|
|
// AdminHandler 后台管理处理器
|
|
type AdminHandler struct {
|
|
noteSvc *service.NoteService
|
|
config *config.Config
|
|
}
|
|
|
|
// NewAdminHandler 创建后台管理处理器
|
|
func NewAdminHandler(noteSvc *service.NoteService, cfg *config.Config) *AdminHandler {
|
|
return &AdminHandler{noteSvc: noteSvc, config: cfg}
|
|
}
|
|
|
|
// LoginPage 登录页面
|
|
func (h *AdminHandler) LoginPage(c *gin.Context) {
|
|
c.HTML(http.StatusOK, "login.html", gin.H{
|
|
"title": "后台管理登录",
|
|
})
|
|
}
|
|
|
|
// Login 验证登录
|
|
func (h *AdminHandler) Login(c *gin.Context) {
|
|
password := c.PostForm("password")
|
|
if password == h.config.AdminPass {
|
|
// 生成随机会话 token
|
|
token, _ := middleware.NewSessionToken()
|
|
// 通过环境变量判断是否启用 HTTPS(生产建议配置)
|
|
secure := c.Request.TLS != nil
|
|
middleware.SetAuthCookie(c, token, secure)
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 0,
|
|
"message": "登录成功",
|
|
})
|
|
return
|
|
}
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"code": 401,
|
|
"message": "密码错误",
|
|
})
|
|
}
|
|
|
|
// Logout 登出
|
|
func (h *AdminHandler) Logout(c *gin.Context) {
|
|
middleware.RevokeSession(middleware.GetAuthToken(c))
|
|
middleware.ClearAuthCookie(c)
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 0,
|
|
"message": "已退出登录",
|
|
})
|
|
}
|
|
|
|
// CheckAuth 检查是否已登录
|
|
func (h *AdminHandler) CheckAuth(c *gin.Context) {
|
|
token := middleware.GetAuthToken(c)
|
|
if middleware.IsValidSession(token) {
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 0,
|
|
"message": "已登录",
|
|
"data": gin.H{
|
|
"authenticated": true,
|
|
},
|
|
})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 0,
|
|
"message": "未登录",
|
|
"data": gin.H{
|
|
"authenticated": false,
|
|
},
|
|
})
|
|
}
|
|
|
|
// IndexPage 后台管理首页
|
|
func (h *AdminHandler) IndexPage(c *gin.Context) {
|
|
token := middleware.GetAuthToken(c)
|
|
if !middleware.IsValidSession(token) {
|
|
c.Redirect(http.StatusFound, "/admin/login")
|
|
return
|
|
}
|
|
c.HTML(http.StatusOK, "index.html", gin.H{
|
|
"title": "笔记管理后台",
|
|
})
|
|
}
|