fix(order): guard renewal activation owner
Some checks failed
Build docker and publish / build (20.15.1) (push) Has been cancelled

This commit is contained in:
shanshanzhong 2026-04-30 12:54:02 -07:00
parent 59b7056a20
commit 280437be91

View File

@ -1356,7 +1356,7 @@ func (l *ActivateOrderLogic) Renewal(ctx context.Context, orderInfo *order.Order
return err
}
userSub, err := l.getUserSubscription(ctx, orderInfo.SubscribeToken)
userSub, err := l.resolveRenewalActivationSubscription(ctx, orderInfo)
if err != nil {
return err
}
@ -1378,7 +1378,7 @@ func (l *ActivateOrderLogic) Renewal(ctx context.Context, orderInfo *order.Order
}
// Trigger user group recalculation (needed when renewing an expired subscription)
l.triggerUserGroupRecalculation(ctx, userInfo.Id)
l.triggerUserGroupRecalculation(ctx, userSub.UserId)
// Clear user subscription cache
err = l.svc.UserModel.ClearSubscribeCache(ctx, userSub)
@ -1386,7 +1386,7 @@ func (l *ActivateOrderLogic) Renewal(ctx context.Context, orderInfo *order.Order
logger.WithContext(ctx).Error("Clear user subscribe cache failed",
logger.Field("error", err.Error()),
logger.Field("subscribe_id", userSub.Id),
logger.Field("user_id", userInfo.Id),
logger.Field("user_id", userSub.UserId),
)
}
@ -1408,6 +1408,75 @@ func (l *ActivateOrderLogic) Renewal(ctx context.Context, orderInfo *order.Order
return nil
}
func (l *ActivateOrderLogic) resolveRenewalActivationSubscription(ctx context.Context, orderInfo *order.Order) (*user.Subscribe, error) {
if orderInfo == nil {
return nil, fmt.Errorf("renewal activation order is nil")
}
userSub, err := l.getUserSubscription(ctx, orderInfo.SubscribeToken)
if err != nil {
return nil, err
}
if orderInfo.UserId <= 0 {
return userSub, nil
}
expectedUserID := orderInfo.SubscriptionUserId
entitlement, err := commonLogic.ResolveEntitlementUser(ctx, l.svc.DB, orderInfo.UserId)
if err != nil {
return nil, err
}
if entitlement != nil && entitlement.Source == commonLogic.EntitlementSourceFamilyOwner && entitlement.EffectiveUserID > 0 {
expectedUserID = entitlement.EffectiveUserID
}
if expectedUserID <= 0 {
if entitlement != nil && entitlement.EffectiveUserID > 0 {
expectedUserID = entitlement.EffectiveUserID
} else {
expectedUserID = orderInfo.UserId
}
}
if userSub.UserId == expectedUserID {
return userSub, nil
}
var target user.Subscribe
err = l.svc.DB.WithContext(ctx).
Model(&user.Subscribe{}).
Where("user_id = ? AND subscribe_id = ? AND token != ''", expectedUserID, orderInfo.SubscribeId).
Where("status IN ?", []int64{0, 1, 2, 3}).
Order("expire_time DESC").
Order("updated_at DESC").
Order("id DESC").
First(&target).Error
if err != nil {
logger.WithContext(ctx).Error("Resolve renewal activation target failed",
logger.Field("error", err.Error()),
logger.Field("order_no", orderInfo.OrderNo),
logger.Field("order_user_id", orderInfo.UserId),
logger.Field("expected_user_id", expectedUserID),
logger.Field("token_owner_user_id", userSub.UserId),
logger.Field("token_user_subscribe_id", userSub.Id),
logger.Field("subscribe_id", orderInfo.SubscribeId),
)
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("renewal activation target mismatch: expected user %d subscription for subscribe %d not found", expectedUserID, orderInfo.SubscribeId)
}
return nil, err
}
commonLogic.SubscriptionTraceInfo(logger.WithContext(ctx), commonLogic.SubscriptionTraceFlowOrder, "renewal_activation_target_redirected",
"[SubscriptionFlow] renewal activation redirected to entitlement owner subscription",
append(commonLogic.OrderTraceFields(orderInfo),
logger.Field("expected_user_id", expectedUserID),
logger.Field("original_user_subscribe_id", userSub.Id),
logger.Field("original_owner_user_id", userSub.UserId),
logger.Field("resolved_user_subscribe_id", target.Id),
logger.Field("resolved_owner_user_id", target.UserId),
)...,
)
return &target, nil
}
// getUserSubscription retrieves user subscription by token
func (l *ActivateOrderLogic) getUserSubscription(ctx context.Context, token string) (*user.Subscribe, error) {
userSub, err := l.svc.UserModel.FindOneSubscribeByToken(ctx, token)