hi-server/internal/logic/public/user/emailTrialGrant.go
shanshanzhong ab38cd4943
Some checks failed
Build docker and publish / build (20.15.1) (push) Failing after 4m44s
x
2026-04-26 21:12:22 -07:00

132 lines
4.8 KiB
Go

package user
import (
"context"
"time"
"github.com/perfect-panel/server/internal/logic/auth"
commonLogic "github.com/perfect-panel/server/internal/logic/common"
"github.com/perfect-panel/server/internal/model/user"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/tool"
"github.com/perfect-panel/server/pkg/uuidx"
)
func tryGrantTrialOnEmailBind(ctx context.Context, svcCtx *svc.ServiceContext, log logger.Logger, ownerUserId int64, email string) {
rc := svcCtx.Config.Register
commonLogic.SubscriptionTraceInfo(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_evaluating",
"[SubscriptionFlow] evaluating email bind trial grant",
logger.Field("owner_user_id", ownerUserId),
logger.Field("email", email),
logger.Field("trial_subscribe_id", rc.TrialSubscribe),
)
if !auth.ShouldAutoGrantTrialOnPublicEmailFlows(rc) {
commonLogic.SubscriptionTraceInfo(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_skipped",
"[SubscriptionFlow] auto trial on public email flow disabled",
logger.Field("email", email),
logger.Field("owner_user_id", ownerUserId),
logger.Field("skip_reason", "public_email_trial_disabled"),
)
return
}
if !auth.ShouldGrantTrialForEmail(rc, email) {
if rc.EnableTrial && rc.EnableTrialEmailWhitelist {
commonLogic.SubscriptionTraceInfo(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_skipped",
"[SubscriptionFlow] email domain not in trial whitelist",
logger.Field("email", email),
logger.Field("owner_user_id", ownerUserId),
logger.Field("skip_reason", "trial_whitelist_rejected"),
)
}
return
}
var count int64
if err := svcCtx.DB.WithContext(ctx).
Model(&user.Subscribe{}).
Where("user_id = ? AND subscribe_id = ?", ownerUserId, rc.TrialSubscribe).
Count(&count).Error; err != nil {
commonLogic.SubscriptionTraceError(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_error",
"[SubscriptionFlow] failed to query existing trial subscription",
logger.Field("owner_user_id", ownerUserId),
logger.Field("email", email),
logger.Field("error", err.Error()),
)
return
}
if count > 0 {
commonLogic.SubscriptionTraceInfo(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_skipped",
"[SubscriptionFlow] trial already exists for owner",
logger.Field("owner_user_id", ownerUserId),
logger.Field("email", email),
logger.Field("skip_reason", "trial_already_exists"),
)
return
}
// Cross-user check: prevent the same real inbox (via dot trick / + alias) from
// getting multiple trials across different accounts.
if auth.NormalizedEmailHasTrial(ctx, svcCtx.DB, email, rc.TrialSubscribe) {
commonLogic.SubscriptionTraceInfo(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_skipped",
"[SubscriptionFlow] normalized email already received a trial elsewhere",
logger.Field("email", email),
logger.Field("owner_user_id", ownerUserId),
logger.Field("skip_reason", "normalized_email_has_trial"),
)
return
}
sub, err := svcCtx.SubscribeModel.FindOne(ctx, rc.TrialSubscribe)
if err != nil {
commonLogic.SubscriptionTraceError(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_error",
"[SubscriptionFlow] failed to load trial subscription template",
logger.Field("owner_user_id", ownerUserId),
logger.Field("email", email),
logger.Field("trial_subscribe_id", rc.TrialSubscribe),
logger.Field("error", err.Error()),
)
return
}
userSub := &user.Subscribe{
UserId: ownerUserId,
OrderId: 0,
SubscribeId: sub.Id,
StartTime: time.Now(),
ExpireTime: tool.AddTime(rc.TrialTimeUnit, rc.TrialTime, time.Now()),
Traffic: sub.Traffic,
Download: 0,
Upload: 0,
Token: uuidx.NewUUID().String(),
UUID: uuidx.NewUUID().String(),
Status: 1,
}
if err = svcCtx.UserModel.InsertSubscribe(ctx, userSub); err != nil {
commonLogic.SubscriptionTraceError(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_error",
"[SubscriptionFlow] failed to create trial subscription for email bind",
append(commonLogic.UserSubscribeTraceFields(userSub),
logger.Field("error", err.Error()),
logger.Field("owner_user_id", ownerUserId),
logger.Field("email", email),
)...,
)
return
}
if svcCtx.NodeModel != nil {
if err = svcCtx.NodeModel.ClearServerAllCache(ctx); err != nil {
log.Errorw("ClearServerAllCache error", logger.Field("error", err.Error()))
}
}
commonLogic.SubscriptionTraceInfo(log, commonLogic.SubscriptionTraceFlowEmailBind, "trial_grant_succeeded",
"[SubscriptionFlow] trial subscription granted after email bind",
append(commonLogic.UserSubscribeTraceFields(userSub),
logger.Field("owner_user_id", ownerUserId),
logger.Field("email", email),
logger.Field("trial_subscribe_id", sub.Id),
)...,
)
}