feat: add Yuheng ticket bind, trial SMS off, shared bindings
Ship ticket-exchange and bind/policy for Z13, keep trial binds SMS-free, allow shared company bindings, and align SyncPage plus sync docs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -216,7 +216,7 @@ func authorizeUserOnlineDB(svcCtx *svc.ServiceContext, w http.ResponseWriter, r
|
||||
uid := authx.UserID(r.Context())
|
||||
tid := syncTenantID(r)
|
||||
if !svcCtx.DBSync.Store().UserOwnsOnlineDB(tid, uid, channelID, online) {
|
||||
authx.WriteError(w, http.StatusForbidden, "无权访问该 online_db_id(非本人 Binding)")
|
||||
authx.WriteError(w, http.StatusForbidden, "无权访问该 online_db_id(非本人 Binding / 非公司共享库)")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -44,6 +44,8 @@ func RegisterHandlers(server *rest.Server, svcCtx *svc.ServiceContext) {
|
||||
{Method: http.MethodPost, Path: "/api/v1/auth/bind-code/redeem", Handler: rl(bindCodeRedeemHandler(svcCtx))},
|
||||
{Method: http.MethodPost, Path: "/api/v1/auth/bind/phone-lookup", Handler: rl(bindPhoneLookupHandler(svcCtx))},
|
||||
{Method: http.MethodPost, Path: "/api/v1/auth/bind/phone-confirm", Handler: rl(bindPhoneConfirmHandler(svcCtx))},
|
||||
{Method: http.MethodGet, Path: "/api/v1/auth/bind/policy", Handler: rl(bindPolicyHandler(svcCtx))},
|
||||
{Method: http.MethodPost, Path: "/api/v1/auth/yuheng/ticket-exchange", Handler: rl(yuhengTicketExchangeHandler(svcCtx))},
|
||||
{Method: http.MethodPost, Path: "/api/v1/auth/register", Handler: rl(registerHandler(svcCtx))},
|
||||
{Method: http.MethodPost, Path: "/api/v1/auth/login", Handler: rl(loginHandler(svcCtx))},
|
||||
{Method: http.MethodPost, Path: "/api/v1/auth/sms/send", Handler: rl(sendLoginSMSHandler(svcCtx))},
|
||||
@@ -388,6 +390,12 @@ func bindPhoneLookupHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func bindPolicyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
httpx.OkJson(w, applogic.NewAuthLogic(r.Context(), svcCtx).BindPolicy())
|
||||
}
|
||||
}
|
||||
|
||||
func bindPhoneConfirmHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req applogic.PhoneConfirmReq
|
||||
@@ -404,6 +412,22 @@ func bindPhoneConfirmHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func yuhengTicketExchangeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req applogic.YuhengTicketExchangeReq
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
authx.WriteError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
resp, err := applogic.NewAuthLogic(r.Context(), svcCtx).ExchangeYuhengTicket(req)
|
||||
if err != nil {
|
||||
authx.WriteError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OkJson(w, resp)
|
||||
}
|
||||
}
|
||||
|
||||
func roleListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
items, err := applogic.NewRoleAdminLogic(r.Context(), svcCtx).List()
|
||||
|
||||
@@ -26,6 +26,21 @@ func syncBindingsListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
list, err = svcCtx.DBSync.Store().ListBindings(tid, localID)
|
||||
} else {
|
||||
list, err = svcCtx.DBSync.Store().ListBindingsFiltered(tid, authx.UserID(r.Context()), localID)
|
||||
if err == nil {
|
||||
// 附带公司共享库 Binding,便于客户端展示
|
||||
all, e2 := svcCtx.DBSync.Store().ListBindings(tid, localID)
|
||||
if e2 == nil {
|
||||
seen := map[string]bool{}
|
||||
for _, b := range list {
|
||||
seen[b.ID] = true
|
||||
}
|
||||
for _, b := range all {
|
||||
if b.Shared && !seen[b.ID] {
|
||||
list = append(list, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
authx.WriteError(w, http.StatusBadRequest, err.Error())
|
||||
@@ -52,8 +67,12 @@ func syncBindingsEnsureHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
body.UserID = uid
|
||||
}
|
||||
} else {
|
||||
// 用户自助:强制绑定到本人,禁止冒用他人 user_id
|
||||
// 用户自助:强制绑定到本人,禁止冒用他人 user_id;禁止自助标共享库
|
||||
body.UserID = uid
|
||||
if body.Shared {
|
||||
authx.WriteError(w, http.StatusForbidden, "仅公司管理员可将 Binding 标为公司共享库(shared)")
|
||||
return
|
||||
}
|
||||
}
|
||||
saved, err := svcCtx.DBSync.Store().EnsureBinding(body)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user