Files
cmr-mini/backend/internal/service/profile_service.go

120 lines
3.1 KiB
Go

package service
import (
"context"
"net/http"
"cmr-backend/internal/apperr"
"cmr-backend/internal/store/postgres"
)
type ProfileService struct {
store *postgres.Store
}
type ProfileResult struct {
User struct {
ID string `json:"id"`
PublicID string `json:"publicId"`
Status string `json:"status"`
Nickname *string `json:"nickname,omitempty"`
AvatarURL *string `json:"avatarUrl,omitempty"`
} `json:"user"`
Bindings struct {
HasMobile bool `json:"hasMobile"`
HasWechatMini bool `json:"hasWechatMini"`
HasWechatUnion bool `json:"hasWechatUnion"`
Items []ProfileBindingItem `json:"items"`
} `json:"bindings"`
RecentSessions []EntrySessionSummary `json:"recentSessions"`
}
type ProfileBindingItem struct {
IdentityType string `json:"identityType"`
Provider string `json:"provider"`
Status string `json:"status"`
CountryCode *string `json:"countryCode,omitempty"`
Mobile *string `json:"mobile,omitempty"`
MaskedLabel string `json:"maskedLabel"`
}
func NewProfileService(store *postgres.Store) *ProfileService {
return &ProfileService{store: store}
}
func (s *ProfileService) GetProfile(ctx context.Context, userID string) (*ProfileResult, error) {
if userID == "" {
return nil, apperr.New(http.StatusUnauthorized, "unauthorized", "user is required")
}
user, err := s.store.GetUserByID(ctx, s.store.Pool(), userID)
if err != nil {
return nil, err
}
if user == nil {
return nil, apperr.New(http.StatusNotFound, "user_not_found", "user not found")
}
identities, err := s.store.ListIdentitiesByUserID(ctx, userID)
if err != nil {
return nil, err
}
sessions, err := s.store.ListSessionsByUserID(ctx, userID, 5)
if err != nil {
return nil, err
}
result := &ProfileResult{}
result.User.ID = user.ID
result.User.PublicID = user.PublicID
result.User.Status = user.Status
result.User.Nickname = user.Nickname
result.User.AvatarURL = user.AvatarURL
for _, identity := range identities {
item := ProfileBindingItem{
IdentityType: identity.IdentityType,
Provider: identity.Provider,
Status: identity.Status,
CountryCode: identity.CountryCode,
Mobile: identity.Mobile,
MaskedLabel: maskIdentity(identity),
}
result.Bindings.Items = append(result.Bindings.Items, item)
switch identity.Provider {
case "mobile":
result.Bindings.HasMobile = true
case "wechat_mini":
result.Bindings.HasWechatMini = true
case "wechat_unionid":
result.Bindings.HasWechatUnion = true
}
}
for i := range sessions {
result.RecentSessions = append(result.RecentSessions, buildEntrySessionSummary(&sessions[i]))
}
return result, nil
}
func maskIdentity(identity postgres.LoginIdentity) string {
if identity.Provider == "mobile" && identity.Mobile != nil {
value := *identity.Mobile
if len(value) >= 7 {
return value[:3] + "****" + value[len(value)-4:]
}
return value
}
if identity.Provider == "wechat_mini" {
return "WeChat Mini bound"
}
if identity.Provider == "wechat_unionid" {
return "WeChat Union bound"
}
return identity.Provider
}