feat: 登录设备管理与编辑器图片上传
- 新增登录设备列表与会话下线(ListLoginDevices/RevokeLoginDevice),按设备指纹识别当前会话 - Markdown 编辑器新增图片插入弹窗与图片上传(ImageInsertModal) - 实时总线、账号守卫与用户事件适配
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/freefire/jiang13-bbs/middleware"
|
||||
"github.com/freefire/jiang13-bbs/model"
|
||||
"github.com/freefire/jiang13-bbs/realtime"
|
||||
"github.com/freefire/jiang13-bbs/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -153,8 +154,8 @@ func (h *Handlers) Register(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
_ = h.Chat.EnsureDefaultMembership(user.ID)
|
||||
// 自动登录:走与 Login 相同的 token 签发链路
|
||||
accessToken, refreshToken, loginUser, err := h.Auth.Login(req.Username, req.Password, c.ClientIP(), c.Request.UserAgent())
|
||||
// 自动登录:走与 Login 相同的 token 签发链路(新注册无旧会话,不会有踢出广播)
|
||||
accessToken, refreshToken, loginUser, _, err := h.Auth.Login(req.Username, req.Password, c.ClientIP(), c.Request.UserAgent())
|
||||
if err != nil {
|
||||
// 签发失败不应让注册白做:仍返回成功,让前端引导去登录页
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
@@ -191,7 +192,7 @@ func (h *Handlers) Login(c *gin.Context) {
|
||||
if !h.quotaResponse(c, wait, e) {
|
||||
return
|
||||
}
|
||||
accessToken, refreshToken, user, err := h.Auth.Login(req.Username, req.Password, c.ClientIP(), c.Request.UserAgent())
|
||||
accessToken, refreshToken, user, kicked, err := h.Auth.Login(req.Username, req.Password, c.ClientIP(), c.Request.UserAgent())
|
||||
if err != nil {
|
||||
h.Ops.RecordFailure(req.Username, c.ClientIP(), cfg)
|
||||
// 登录失败也留痕:用户存在时带 user_id(封禁/错密),不存在时为 0
|
||||
@@ -212,6 +213,14 @@ func (h *Handlers) Login(c *gin.Context) {
|
||||
// dev 模式不设 Secure,生产环境需 HTTPS
|
||||
h.Ops.ClearFailure(req.Username)
|
||||
setAuthCookies(c, accessToken, refreshToken, !h.Cfg.DevMode)
|
||||
// 真·单会话:本次登录顶掉了所有旧会话,即时广播告知被踢设备(旧浏览器 WS 在线则
|
||||
// 当场弹"登录已失效",无需等 access token 过期或硬刷新才发现)
|
||||
if kicked > 0 {
|
||||
h.Hub.BroadcastUser(user.ID, realtime.Envelope{
|
||||
Type: realtime.EventSessionReplaced,
|
||||
Data: gin.H{"reason": "new_login"},
|
||||
})
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"user": gin.H{
|
||||
"id": user.ID,
|
||||
@@ -338,6 +347,11 @@ func (h *Handlers) RevokeLoginDevice(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "剔除设备失败"})
|
||||
return
|
||||
}
|
||||
// 被剔除设备即时感知:WS 在线则当场弹"登录已失效",无需等 token 失效
|
||||
h.Hub.BroadcastUser(claims.ID, realtime.Envelope{
|
||||
Type: realtime.EventSessionReplaced,
|
||||
Data: gin.H{"reason": "device_revoked"},
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user