alist/server/handles/session.go
okatu-loli af2a115547 feat(session): Added session cleanup functionality
- Added the `/clean` route to the route for session cleanup
- Added the `DeleteInactiveSessions` method to support deleting inactive sessions by user ID
- Added the `DeleteSessionByID` method to delete a specific session by session ID
- Defined the `CleanSessionsReq` request structure to support passing a user ID or session ID
- Implemented the `CleanSessions` interface logic to perform corresponding session cleanup operations based on the request parameters
2025-09-09 22:06:17 +08:00

127 lines
2.8 KiB
Go

package handles
import (
"github.com/alist-org/alist/v3/internal/db"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/server/common"
"github.com/gin-gonic/gin"
)
type SessionResp struct {
SessionID string `json:"session_id"`
UserID uint `json:"user_id,omitempty"`
LastActive int64 `json:"last_active"`
Status int `json:"status"`
UA string `json:"ua"`
IP string `json:"ip"`
}
func ListMySessions(c *gin.Context) {
user := c.MustGet("user").(*model.User)
sessions, err := db.ListSessionsByUser(user.ID)
if err != nil {
common.ErrorResp(c, err, 500)
return
}
resp := make([]SessionResp, len(sessions))
for i, s := range sessions {
resp[i] = SessionResp{
SessionID: s.DeviceKey,
LastActive: s.LastActive,
Status: s.Status,
UA: s.UserAgent,
IP: s.IP,
}
}
common.SuccessResp(c, resp)
}
type EvictSessionReq struct {
SessionID string `json:"session_id"`
}
type CleanSessionsReq struct {
UserID *uint `json:"user_id"`
SessionID string `json:"session_id"`
}
func EvictMySession(c *gin.Context) {
var req EvictSessionReq
if err := c.ShouldBindJSON(&req); err != nil {
common.ErrorResp(c, err, 400)
return
}
user := c.MustGet("user").(*model.User)
if _, err := db.GetSession(user.ID, req.SessionID); err != nil {
common.ErrorResp(c, err, 400)
return
}
if err := db.MarkInactive(req.SessionID); err != nil {
common.ErrorResp(c, err, 500)
return
}
common.SuccessResp(c)
}
func ListSessions(c *gin.Context) {
sessions, err := db.ListSessions()
if err != nil {
common.ErrorResp(c, err, 500)
return
}
resp := make([]SessionResp, len(sessions))
for i, s := range sessions {
resp[i] = SessionResp{
SessionID: s.DeviceKey,
UserID: s.UserID,
LastActive: s.LastActive,
Status: s.Status,
UA: s.UserAgent,
IP: s.IP,
}
}
common.SuccessResp(c, resp)
}
func EvictSession(c *gin.Context) {
var req EvictSessionReq
if err := c.ShouldBindJSON(&req); err != nil {
common.ErrorResp(c, err, 400)
return
}
if err := db.MarkInactive(req.SessionID); err != nil {
common.ErrorResp(c, err, 500)
return
}
common.SuccessResp(c)
}
func CleanSessions(c *gin.Context) {
var req CleanSessionsReq
if err := c.ShouldBindJSON(&req); err != nil {
common.ErrorResp(c, err, 400)
return
}
if req.SessionID != "" {
if err := db.DeleteSessionByID(req.SessionID); err != nil {
common.ErrorResp(c, err, 500)
return
}
common.SuccessResp(c)
return
}
if req.UserID != nil {
if err := db.DeleteInactiveSessions(req.UserID); err != nil {
common.ErrorResp(c, err, 500)
return
}
common.SuccessResp(c)
return
}
if err := db.DeleteInactiveSessions(nil); err != nil {
common.ErrorResp(c, err, 500)
return
}
common.SuccessResp(c)
}