diff --git a/.github/workflows/docker-buildx.bak b/.github/workflows/docker-buildx.bak index b40aa6fef..cbd6440e4 100644 --- a/.github/workflows/docker-buildx.bak +++ b/.github/workflows/docker-buildx.bak @@ -1,17 +1,3 @@ -# Copyright © 2023 OpenIM open source community. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - name: Docker Buildx Images CI on: @@ -40,11 +26,12 @@ jobs: install: true - name: Cache Docker layers - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: ${{ runner.os }}-buildx- + restore-keys: | + ${{ runner.os }}-buildx- - name: Log in to GitHub Container Registry uses: docker/login-action@v3 diff --git a/config/chat-rpc-chat.yml b/config/chat-rpc-chat.yml index d015ad63f..329cfd51f 100644 --- a/config/chat-rpc-chat.yml +++ b/config/chat-rpc-chat.yml @@ -33,3 +33,5 @@ liveKit: url: "ws://127.0.0.1:7880" # LIVEKIT_URL, LiveKit server address and port key: "APIGPW3gnFTzqHH" secret: "23ztfSqsfQ8hKkHzHTl3Z4bvaxro0snjk5jwbp5p6Q3" + +allowRegister: true diff --git a/go.mod b/go.mod index 2b84c4af7..6560dd1ac 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/openimsdk/gomake v0.0.14-alpha.5 github.com/openimsdk/protocol v0.0.72 - github.com/openimsdk/tools v0.0.50-alpha.15 + github.com/openimsdk/tools v0.0.50-alpha.20 github.com/redis/go-redis/v9 v9.5.1 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 diff --git a/go.sum b/go.sum index a4f7c8ac8..b6f181fe2 100644 --- a/go.sum +++ b/go.sum @@ -189,8 +189,8 @@ github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCF github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI= github.com/openimsdk/protocol v0.0.72 h1:K+vslwaR7lDXyBzb07UuEQITaqsgighz7NyXVIWsu6A= github.com/openimsdk/protocol v0.0.72/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= -github.com/openimsdk/tools v0.0.50-alpha.15 h1:HV9aKZ4vvCZCGG4wFDsgUONkkdJeCcrFNn3BT52nUVQ= -github.com/openimsdk/tools v0.0.50-alpha.15/go.mod h1:h1cYmfyaVtgFbKmb1Cfsl8XwUOMTt8ubVUQrdGtsUh4= +github.com/openimsdk/tools v0.0.50-alpha.20 h1:TUCZOwaea983Qj1MCbiGZUBlwBkTMwTF9SLS0WQcsJs= +github.com/openimsdk/tools v0.0.50-alpha.20/go.mod h1:h1cYmfyaVtgFbKmb1Cfsl8XwUOMTt8ubVUQrdGtsUh4= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= diff --git a/internal/api/admin/admin.go b/internal/api/admin/admin.go index 7e0a44893..6bc4b921c 100644 --- a/internal/api/admin/admin.go +++ b/internal/api/admin/admin.go @@ -1,17 +1,3 @@ -// Copyright © 2023 OpenIM open source community. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package admin import ( @@ -72,7 +58,7 @@ func (o *Api) AdminLogin(c *gin.Context) { return } imAdminUserID := o.GetDefaultIMAdminUserID() - imToken, err := o.imApiCaller.GetAdminToken(c, imAdminUserID) + imToken, err := o.imApiCaller.ImAdminTokenWithDefaultAdmin(c) if err != nil { apiresp.GinError(c, err) return @@ -173,6 +159,12 @@ func (o *Api) AddUserAccount(c *gin.Context) { return } + if resp, err := o.adminClient.FindDefaultFriend(c, &admin.FindDefaultFriendReq{}); err == nil { + _ = o.imApiCaller.ImportFriend(c, req.User.UserID, resp.UserIDs) + } + if resp, err := o.adminClient.FindDefaultGroup(c, &admin.FindDefaultGroupReq{}); err == nil { + _ = o.imApiCaller.InviteToGroup(c, req.User.UserID, resp.GroupIDs) + } apiresp.GinSuccess(c, nil) } @@ -547,6 +539,7 @@ func (o *Api) registerChatUser(ctx context.Context, ip string, users []*chat.Reg if err = o.imApiCaller.RegisterUser(ctx, []*sdkws.UserInfo{userInfo}); err != nil { return err } + if resp, err := o.adminClient.FindDefaultFriend(ctx, &admin.FindDefaultFriendReq{}); err == nil { _ = o.imApiCaller.ImportFriend(ctx, respRegisterUser.UserID, resp.UserIDs) } @@ -571,3 +564,11 @@ func (o *Api) BatchImportTemplate(c *gin.Context) { c.Header("ETag", md5Val) c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", config.ImportTemplate) } + +func (o *Api) SetAllowRegister(c *gin.Context) { + a2r.Call(chat.ChatClient.SetAllowRegister, o.chatClient, c) +} + +func (o *Api) GetAllowRegister(c *gin.Context) { + a2r.Call(chat.ChatClient.GetAllowRegister, o.chatClient, c) +} diff --git a/internal/api/admin/start.go b/internal/api/admin/start.go index 05a1799b3..fc53c94f8 100644 --- a/internal/api/admin/start.go +++ b/internal/api/admin/start.go @@ -81,6 +81,10 @@ func SetAdminRoute(router gin.IRouter, admin *Api, mw *chatmw.MW) { importGroup.POST("/xlsx", mw.CheckAdmin, admin.ImportUserByXlsx) importGroup.GET("/xlsx", admin.BatchImportTemplate) + allowRegisterGroup := router.Group("/user/allow_register", mw.CheckAdmin) + allowRegisterGroup.POST("/get", admin.GetAllowRegister) + allowRegisterGroup.POST("/set", admin.SetAllowRegister) + defaultRouter := router.Group("/default", mw.CheckAdmin) defaultUserRouter := defaultRouter.Group("/user") defaultUserRouter.POST("/add", admin.AddDefaultFriend) // Add default friend at registration diff --git a/internal/rpc/chat/callback.go b/internal/rpc/chat/callback.go index b355d7660..d4bfe5558 100644 --- a/internal/rpc/chat/callback.go +++ b/internal/rpc/chat/callback.go @@ -47,7 +47,7 @@ func (o *chatSvr) OpenIMCallback(ctx context.Context, req *chat.OpenIMCallbackRe if err := json.Unmarshal([]byte(req.Body), &data); err != nil { return nil, errs.Wrap(err) } - user, err := o.Database.GetAttribute(ctx, data.ToUserID) + user, err := o.Database.TakeAttributeByUserID(ctx, data.ToUserID) if err != nil { return nil, err } diff --git a/internal/rpc/chat/login.go b/internal/rpc/chat/login.go index 59990302d..e672ccddf 100644 --- a/internal/rpc/chat/login.go +++ b/internal/rpc/chat/login.go @@ -1,17 +1,3 @@ -// Copyright © 2023 OpenIM open source community. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package chat import ( @@ -50,7 +36,7 @@ func (o *chatSvr) SendVerifyCode(ctx context.Context, req *chat.SendVerifyCodeRe if req.AreaCode == "" || req.PhoneNumber == "" { return nil, errs.ErrArgs.WrapMsg("area code or phone number is empty") } - if req.AreaCode[0] != '+' { + if !strings.HasPrefix(req.AreaCode, "+") { req.AreaCode = "+" + req.AreaCode } if _, err := strconv.ParseUint(req.AreaCode[1:], 10, 64); err != nil { @@ -59,22 +45,10 @@ func (o *chatSvr) SendVerifyCode(ctx context.Context, req *chat.SendVerifyCodeRe if _, err := strconv.ParseUint(req.PhoneNumber, 10, 64); err != nil { return nil, errs.ErrArgs.WrapMsg("phone number must be number") } - _, err := o.Database.TakeAttributeByPhone(ctx, req.AreaCode, req.PhoneNumber) - if err == nil { - return nil, eerrs.ErrPhoneAlreadyRegister.WrapMsg("phone already register") - } else if !dbutil.IsDBNotFound(err) { - return nil, err - } } else { if err := chat.EmailCheck(req.Email); err != nil { return nil, errs.ErrArgs.WrapMsg("email must be right") } - _, err := o.Database.TakeAttributeByEmail(ctx, req.Email) - if err == nil { - return nil, eerrs.ErrEmailAlreadyRegister.WrapMsg("email already register") - } else if !dbutil.IsDBNotFound(err) { - return nil, err - } } conf, err := o.Admin.GetConfig(ctx) if err != nil { @@ -245,16 +219,14 @@ func (o *chatSvr) RegisterUser(ctx context.Context, req *chat.RegisterUserReq) ( if err != nil { return nil, err } - if req.User == nil { - return nil, errs.ErrArgs.WrapMsg("user is nil") - } - if req.User.Email == "" { - if (req.User.AreaCode == "" && req.User.PhoneNumber != "") || (req.User.AreaCode != "" && req.User.PhoneNumber == "") { - return nil, errs.ErrArgs.WrapMsg("area code or phone number error, no email provide") - } + if err = o.checkRegisterInfo(ctx, req.User, isAdmin); err != nil { + return nil, err } var usedInvitationCode bool if !isAdmin { + if !o.AllowRegister { + return nil, errs.ErrNoPermission.WrapMsg("register user is disabled") + } if req.User.UserID != "" { return nil, errs.ErrNoPermission.WrapMsg("only admin can set user id") } @@ -308,43 +280,39 @@ func (o *chatSvr) RegisterUser(ctx context.Context, req *chat.RegisterUserReq) ( return nil, err } } - var registerType int32 + var ( + credentials []*chatdb.Credential + registerType int32 + ) + if req.User.PhoneNumber != "" { - if req.User.AreaCode[0] != '+' { - req.User.AreaCode = "+" + req.User.AreaCode - } - if _, err := strconv.ParseUint(req.User.AreaCode[1:], 10, 64); err != nil { - return nil, errs.ErrArgs.WrapMsg("area code must be number") - } - if _, err := strconv.ParseUint(req.User.PhoneNumber, 10, 64); err != nil { - return nil, errs.ErrArgs.WrapMsg("phone number must be number") - } - _, err := o.Database.TakeAttributeByPhone(ctx, req.User.AreaCode, req.User.PhoneNumber) - if err == nil { - return nil, eerrs.ErrPhoneAlreadyRegister.Wrap() - } else if !dbutil.IsDBNotFound(err) { - return nil, err - } registerType = constant.PhoneRegister + credentials = append(credentials, &chatdb.Credential{ + UserID: req.User.UserID, + Account: BuildCredentialPhone(req.User.AreaCode, req.User.PhoneNumber), + Type: constant.CredentialPhone, + AllowChange: true, + }) } if req.User.Account != "" { - _, err := o.Database.TakeAttributeByAccount(ctx, req.User.Account) - if err == nil { - return nil, eerrs.ErrAccountAlreadyRegister.Wrap() - } else if !dbutil.IsDBNotFound(err) { - return nil, err - } + credentials = append(credentials, &chatdb.Credential{ + UserID: req.User.UserID, + Account: req.User.Account, + Type: constant.CredentialAccount, + AllowChange: true, + }) + registerType = constant.AccountRegister } if req.User.Email != "" { - _, err := o.Database.TakeAttributeByEmail(ctx, req.User.Email) registerType = constant.EmailRegister - if err == nil { - return nil, eerrs.ErrEmailAlreadyRegister.Wrap() - } else if !dbutil.IsDBNotFound(err) { - return nil, err - } + credentials = append(credentials, &chatdb.Credential{ + UserID: req.User.UserID, + Account: req.User.Email, + Type: constant.CredentialEmail, + AllowChange: true, + }) } register := &chatdb.Register{ UserID: req.User.UserID, @@ -362,6 +330,7 @@ func (o *chatSvr) RegisterUser(ctx context.Context, req *chat.RegisterUserReq) ( ChangeTime: register.CreateTime, CreateTime: register.CreateTime, } + attribute := &chatdb.Attribute{ UserID: req.User.UserID, Account: req.User.Account, @@ -379,7 +348,7 @@ func (o *chatSvr) RegisterUser(ctx context.Context, req *chat.RegisterUserReq) ( AllowAddFriend: constant.DefaultAllowAddFriend, RegisterType: registerType, } - if err := o.Database.RegisterUser(ctx, register, account, attribute); err != nil { + if err := o.Database.RegisterUser(ctx, register, account, attribute, credentials); err != nil { return nil, err } if usedInvitationCode { @@ -405,33 +374,42 @@ func (o *chatSvr) Login(ctx context.Context, req *chat.LoginReq) (*chat.LoginRes if req.Password == "" && req.VerifyCode == "" { return nil, errs.ErrArgs.WrapMsg("password or code must be set") } - var err error - var attribute *chatdb.Attribute - if req.Account != "" { - attribute, err = o.Database.GetAttributeByAccount(ctx, req.Account) - } else if req.PhoneNumber != "" { + if req.Password == "" { + return nil, errs.ErrArgs.WrapMsg("password must be set") + } + var ( + err error + credential *chatdb.Credential + acc string + ) + + switch { + case req.Account != "": + acc = req.Account + case req.PhoneNumber != "": if req.AreaCode == "" { return nil, errs.ErrArgs.WrapMsg("area code must") } - if req.AreaCode[0] != '+' { + if !strings.HasPrefix(req.AreaCode, "+") { req.AreaCode = "+" + req.AreaCode } if _, err := strconv.ParseUint(req.AreaCode[1:], 10, 64); err != nil { return nil, errs.ErrArgs.WrapMsg("area code must be number") } - attribute, err = o.Database.GetAttributeByPhone(ctx, req.AreaCode, req.PhoneNumber) - } else if req.Email != "" { - attribute, err = o.Database.GetAttributeByEmail(ctx, req.Email) - } else { - err = errs.ErrArgs.WrapMsg("account or phone number or email must be set") + acc = BuildCredentialPhone(req.AreaCode, req.PhoneNumber) + case req.Email != "": + acc = req.Email + default: + return nil, errs.ErrArgs.WrapMsg("account or phone number or email must be set") } + credential, err = o.Database.TakeCredentialByAccount(ctx, acc) if err != nil { if dbutil.IsDBNotFound(err) { return nil, eerrs.ErrAccountNotFound.WrapMsg("user unregistered") } return nil, err } - if err := o.Admin.CheckLogin(ctx, attribute.UserID, req.Ip); err != nil { + if err := o.Admin.CheckLogin(ctx, credential.UserID, req.Ip); err != nil { return nil, err } var verifyCodeID *string @@ -450,7 +428,7 @@ func (o *chatSvr) Login(ctx context.Context, req *chat.LoginReq) (*chat.LoginRes verifyCodeID = &id } } else { - account, err := o.Database.GetAccount(ctx, attribute.UserID) + account, err := o.Database.TakeAccount(ctx, credential.UserID) if err != nil { return nil, err } @@ -458,12 +436,12 @@ func (o *chatSvr) Login(ctx context.Context, req *chat.LoginReq) (*chat.LoginRes return nil, eerrs.ErrPassword.Wrap() } } - chatToken, err := o.Admin.CreateToken(ctx, attribute.UserID, constant.NormalUser) + chatToken, err := o.Admin.CreateToken(ctx, credential.UserID, constant.NormalUser) if err != nil { return nil, err } record := &chatdb.UserLoginRecord{ - UserID: attribute.UserID, + UserID: credential.UserID, LoginTime: time.Now(), IP: req.Ip, DeviceID: req.DeviceID, @@ -477,7 +455,7 @@ func (o *chatSvr) Login(ctx context.Context, req *chat.LoginReq) (*chat.LoginRes return nil, err } } - resp.UserID = attribute.UserID + resp.UserID = credential.UserID resp.ChatToken = chatToken.Token return resp, nil } diff --git a/internal/rpc/chat/password.go b/internal/rpc/chat/password.go index 6235a2df7..7c9657a0a 100644 --- a/internal/rpc/chat/password.go +++ b/internal/rpc/chat/password.go @@ -41,13 +41,13 @@ func (o *chatSvr) ResetPassword(ctx context.Context, req *chat.ResetPasswordReq) } if req.Email == "" { - attribute, err := o.Database.GetAttributeByPhone(ctx, req.AreaCode, req.PhoneNumber) + attribute, err := o.Database.TakeAttributeByPhone(ctx, req.AreaCode, req.PhoneNumber) if err != nil { return nil, err } err = o.Database.UpdatePasswordAndDeleteVerifyCode(ctx, attribute.UserID, req.Password, verifyCodeID) } else { - attribute, err := o.Database.GetAttributeByEmail(ctx, req.Email) + attribute, err := o.Database.TakeAttributeByEmail(ctx, req.Email) if err != nil { return nil, err } diff --git a/internal/rpc/chat/register.go b/internal/rpc/chat/register.go new file mode 100644 index 000000000..9eb610044 --- /dev/null +++ b/internal/rpc/chat/register.go @@ -0,0 +1,15 @@ +package chat + +import ( + "context" + "github.com/openimsdk/chat/pkg/protocol/chat" +) + +func (o *chatSvr) SetAllowRegister(ctx context.Context, req *chat.SetAllowRegisterReq) (*chat.SetAllowRegisterResp, error) { + o.AllowRegister = req.AllowRegister + return &chat.SetAllowRegisterResp{}, nil +} + +func (o *chatSvr) GetAllowRegister(ctx context.Context, req *chat.GetAllowRegisterReq) (*chat.GetAllowRegisterResp, error) { + return &chat.GetAllowRegisterResp{AllowRegister: o.AllowRegister}, nil +} diff --git a/internal/rpc/chat/start.go b/internal/rpc/chat/start.go index 71939dd54..901b2c5dd 100644 --- a/internal/rpc/chat/start.go +++ b/internal/rpc/chat/start.go @@ -68,6 +68,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg Len: config.RpcConfig.VerifyCode.Len, } srv.Livekit = rtc.NewLiveKit(config.RpcConfig.LiveKit.Key, config.RpcConfig.LiveKit.Secret, config.RpcConfig.LiveKit.URL) + srv.AllowRegister = config.RpcConfig.AllowRegister chat.RegisterChatServer(server, &srv) return nil } @@ -80,6 +81,7 @@ type chatSvr struct { Code verifyCode Livekit *rtc.LiveKit ChatAdminUserID string + AllowRegister bool } func (o *chatSvr) WithAdminUser(ctx context.Context) context.Context { diff --git a/internal/rpc/chat/update.go b/internal/rpc/chat/update.go index 4579f1c3e..8f69de2f2 100644 --- a/internal/rpc/chat/update.go +++ b/internal/rpc/chat/update.go @@ -15,6 +15,8 @@ package chat import ( + "github.com/openimsdk/chat/pkg/common/constant" + chatdb "github.com/openimsdk/chat/pkg/common/db/table/chat" "time" "github.com/openimsdk/tools/errs" @@ -68,3 +70,56 @@ func ToDBAttributeUpdate(req *chat.UpdateUserInfoReq) (map[string]any, error) { //} return update, nil } + +func ToDBCredentialUpdate(req *chat.UpdateUserInfoReq, allowChange bool) ([]*chatdb.Credential, []*chatdb.Credential, error) { + update := make([]*chatdb.Credential, 0) + del := make([]*chatdb.Credential, 0) + if req.Account != nil { + if req.Account.GetValue() == "" { + del = append(del, &chatdb.Credential{ + UserID: req.UserID, + Type: constant.CredentialAccount, + }) + } else { + update = append(update, &chatdb.Credential{ + UserID: req.UserID, + Account: req.Account.GetValue(), + Type: constant.CredentialAccount, + AllowChange: allowChange, + }) + } + } + + if req.Email != nil { + if req.Email.GetValue() == "" { + del = append(del, &chatdb.Credential{ + UserID: req.UserID, + Type: constant.CredentialEmail, + }) + } else { + update = append(update, &chatdb.Credential{ + UserID: req.UserID, + Account: req.Account.GetValue(), + Type: constant.CredentialEmail, + AllowChange: allowChange, + }) + } + } + if req.PhoneNumber != nil { + if req.PhoneNumber.GetValue() == "" { + del = append(del, &chatdb.Credential{ + UserID: req.UserID, + Type: constant.CredentialPhone, + }) + } else { + update = append(update, &chatdb.Credential{ + UserID: req.UserID, + Account: BuildCredentialPhone(req.AreaCode.GetValue(), req.PhoneNumber.GetValue()), + Type: constant.CredentialPhone, + AllowChange: allowChange, + }) + } + } + + return update, del, nil +} diff --git a/internal/rpc/chat/user.go b/internal/rpc/chat/user.go index ce789613a..057cc6d78 100644 --- a/internal/rpc/chat/user.go +++ b/internal/rpc/chat/user.go @@ -16,6 +16,12 @@ package chat import ( "context" + "errors" + "github.com/openimsdk/chat/pkg/eerrs" + "github.com/openimsdk/protocol/wrapperspb" + "github.com/openimsdk/tools/utils/stringutil" + "strconv" + "strings" "time" "github.com/openimsdk/chat/pkg/common/db/dbutil" @@ -27,83 +33,118 @@ import ( "github.com/openimsdk/chat/pkg/common/constant" "github.com/openimsdk/chat/pkg/common/mctx" - "github.com/openimsdk/chat/pkg/eerrs" "github.com/openimsdk/chat/pkg/protocol/chat" "github.com/openimsdk/tools/errs" ) func (o *chatSvr) checkUpdateInfo(ctx context.Context, req *chat.UpdateUserInfoReq) error { - attribute, err := o.Database.TakeAttributeByUserID(ctx, req.UserID) + if req.AreaCode != nil || req.PhoneNumber != nil { + if !(req.AreaCode != nil && req.PhoneNumber != nil) { + return errs.ErrArgs.WrapMsg("areaCode and phoneNumber must be set together") + } + if req.AreaCode.Value == "" || req.PhoneNumber.Value == "" { + if req.AreaCode.Value != req.PhoneNumber.Value { + return errs.ErrArgs.WrapMsg("areaCode and phoneNumber must be set together") + } + } + } + if req.UserID == "" { + return errs.ErrArgs.WrapMsg("user id is empty") + } + + credentials, err := o.Database.TakeCredentialsByUserID(ctx, req.UserID) if err != nil { return err + } else if len(credentials) == 0 { + return errs.ErrArgs.WrapMsg("user not found") } - checkEmail := func() error { - if req.Email == nil { - return nil - } - if req.Email.Value == attribute.Email { - req.Email = nil - return nil + var ( + credNum, delNum, addNum = len(credentials), 0, 0 + ) + + addFunc := func(s *wrapperspb.StringValue) { + if s != nil { + if s.Value != "" { + addNum++ + } } - if req.Email.Value == "" { - if !(attribute.Account != "" || (attribute.AreaCode != "" && attribute.PhoneNumber != "")) { - return errs.ErrArgs.WrapMsg("a login method must exist") + } + + for _, s := range []*wrapperspb.StringValue{req.Account, req.PhoneNumber, req.Email} { + addFunc(s) + } + + for _, credential := range credentials { + switch credential.Type { + case constant.CredentialAccount: + if req.Account != nil { + if req.Account.Value == credential.Account { + req.Account = nil + } else if req.Account.Value == "" { + delNum += 1 + } } - return nil - } else { - if _, err := o.Database.GetAttributeByEmail(ctx, req.Email.Value); err == nil { - return errs.ErrDuplicateKey.WrapMsg("email already exists") - } else if !dbutil.IsDBNotFound(err) { - return err + case constant.CredentialPhone: + if req.PhoneNumber != nil { + phoneAccount := BuildCredentialPhone(req.AreaCode.Value, req.PhoneNumber.Value) + if phoneAccount == credential.Account { + req.AreaCode = nil + req.PhoneNumber = nil + } else if req.PhoneNumber.Value == "" { + delNum += 1 + } + } + case constant.CredentialEmail: + if req.Email != nil { + if req.Email.Value == credential.Account { + req.Email = nil + } else if req.Email.Value == "" { + delNum += 1 + } } } - return nil } - checkPhone := func() error { - if req.AreaCode == nil { - return nil + + if addNum+credNum-delNum <= 0 { + return errs.ErrArgs.WrapMsg("a login method must exist") + } + + if req.PhoneNumber.GetValue() != "" { + if !strings.HasPrefix(req.AreaCode.GetValue(), "+") { + req.AreaCode.Value = "+" + req.AreaCode.Value } - if req.AreaCode.Value == attribute.AreaCode && req.PhoneNumber.Value == attribute.PhoneNumber { - req.AreaCode = nil - req.PhoneNumber = nil - return nil + if _, err := strconv.ParseUint(req.AreaCode.Value[1:], 10, 64); err != nil { + return errs.ErrArgs.WrapMsg("area code must be number") } - if req.AreaCode.Value == "" || req.PhoneNumber.Value == "" { - if attribute.Email == "" || attribute.Account == "" { - return errs.ErrArgs.WrapMsg("a login method must exist") - } - } else { - if _, err := o.Database.GetAttributeByPhone(ctx, req.AreaCode.Value, req.PhoneNumber.Value); err == nil { - return errs.ErrDuplicateKey.WrapMsg("phone number already exists") - } else if !dbutil.IsDBNotFound(err) { - return err - } + if _, err := strconv.ParseUint(req.PhoneNumber.GetValue(), 10, 64); err != nil { + return errs.ErrArgs.WrapMsg("phone number must be number") } - return nil - } - checkAccount := func() error { - if req.Account == nil { - return nil + _, err := o.Database.TakeCredentialByAccount(ctx, BuildCredentialPhone(req.AreaCode.GetValue(), req.PhoneNumber.GetValue())) + if err == nil { + return eerrs.ErrPhoneAlreadyRegister.Wrap() + } else if !dbutil.IsDBNotFound(err) { + return err } - if req.Account.Value == attribute.Account { - req.Account = nil - return nil + } + if req.Account.GetValue() != "" { + if !stringutil.IsAlphanumeric(req.Account.GetValue()) { + return errs.ErrArgs.WrapMsg("account must be alphanumeric") } - if req.Account.Value == "" { - if !(attribute.Email == "" && (attribute.AreaCode == "" || attribute.PhoneNumber == "")) { - return errs.ErrArgs.WrapMsg("a login method must exist") - } - } else { - if _, err := o.Database.GetAttributeByAccount(ctx, req.Account.Value); err == nil { - return errs.ErrDuplicateKey.WrapMsg("account already exists") - } else if !dbutil.IsDBNotFound(err) { - return err - } + _, err := o.Database.TakeCredentialByAccount(ctx, req.Account.GetValue()) + if err == nil { + return eerrs.ErrAccountAlreadyRegister.Wrap() + } else if !dbutil.IsDBNotFound(err) { + return err } - return nil } - for _, fn := range []func() error{checkEmail, checkPhone, checkAccount} { - if err := fn(); err != nil { + if req.Email.GetValue() != "" { + if !stringutil.IsValidEmail(req.Email.GetValue()) { + return errs.ErrArgs.WrapMsg("invalid email") + } + _, err := o.Database.TakeCredentialByAccount(ctx, req.Email.GetValue()) + if err == nil { + return eerrs.ErrAccountAlreadyRegister.Wrap() + } else if !dbutil.IsDBNotFound(err) { return err } } @@ -111,56 +152,39 @@ func (o *chatSvr) checkUpdateInfo(ctx context.Context, req *chat.UpdateUserInfoR } func (o *chatSvr) UpdateUserInfo(ctx context.Context, req *chat.UpdateUserInfoReq) (*chat.UpdateUserInfoResp, error) { - if req.AreaCode != nil || req.PhoneNumber != nil { - if !(req.AreaCode != nil && req.PhoneNumber != nil) { - return nil, errs.ErrArgs.WrapMsg("areaCode and phoneNumber must be set together") - } - if req.AreaCode.Value == "" || req.PhoneNumber.Value == "" { - if req.AreaCode.Value != req.PhoneNumber.Value { - return nil, errs.ErrArgs.WrapMsg("areaCode and phoneNumber must be set together") - } - } - } opUserID, userType, err := mctx.Check(ctx) if err != nil { return nil, err } - if req.UserID == "" { - return nil, errs.ErrArgs.WrapMsg("user id is empty") + + if err = o.checkUpdateInfo(ctx, req); err != nil { + return nil, err } + switch userType { case constant.NormalUser: - //if req.UserID == "" { - // req.UserID = opUserID - //} + if req.RegisterType != nil { + return nil, errs.ErrNoPermission.WrapMsg("registerType can not be updated") + } if req.UserID != opUserID { return nil, errs.ErrNoPermission.WrapMsg("only admin can update other user info") } - if req.AreaCode != nil { - return nil, errs.ErrNoPermission.WrapMsg("areaCode can not be updated") - } - if req.PhoneNumber != nil { - return nil, errs.ErrNoPermission.WrapMsg("phoneNumber can not be updated") - } - if req.Account != nil { - return nil, errs.ErrNoPermission.WrapMsg("account can not be updated") - } - if req.Level != nil { - return nil, errs.ErrNoPermission.WrapMsg("level can not be updated") - } + case constant.AdminUser: default: return nil, errs.ErrNoPermission.WrapMsg("user type error") } - if err := o.checkUpdateInfo(ctx, req); err != nil { + + update, err := ToDBAttributeUpdate(req) + if err != nil { return nil, err } - update, err := ToDBAttributeUpdate(req) + credUpdate, credDel, err := ToDBCredentialUpdate(req, true) if err != nil { return nil, err } if len(update) > 0 { - if err := o.Database.UpdateUseInfo(ctx, req.UserID, update); err != nil { + if err := o.Database.UpdateUseInfo(ctx, req.UserID, update, credUpdate, credDel); err != nil { return nil, err } } @@ -185,7 +209,7 @@ func (o *chatSvr) AddUserAccount(ctx context.Context, req *chat.AddUserAccountRe return nil, err } - if err := o.checkTheUniqueness(ctx, req); err != nil { + if err := o.checkRegisterInfo(ctx, req.User, true); err != nil { return nil, err } @@ -205,6 +229,44 @@ func (o *chatSvr) AddUserAccount(ctx context.Context, req *chat.AddUserAccountRe if req.User.UserID == "" { return nil, errs.ErrInternalServer.WrapMsg("gen user id failed") } + } else { + _, err := o.Database.GetUser(ctx, req.User.UserID) + if err == nil { + return nil, errs.ErrArgs.WrapMsg("appoint user id already register") + } else if !dbutil.IsDBNotFound(err) { + return nil, err + } + } + + var ( + credentials []*chatdb.Credential + ) + + if req.User.PhoneNumber != "" { + credentials = append(credentials, &chatdb.Credential{ + UserID: req.User.UserID, + Account: BuildCredentialPhone(req.User.AreaCode, req.User.PhoneNumber), + Type: constant.CredentialPhone, + AllowChange: true, + }) + } + + if req.User.Account != "" { + credentials = append(credentials, &chatdb.Credential{ + UserID: req.User.UserID, + Account: req.User.Account, + Type: constant.CredentialAccount, + AllowChange: true, + }) + } + + if req.User.Email != "" { + credentials = append(credentials, &chatdb.Credential{ + UserID: req.User.UserID, + Account: req.User.Email, + Type: constant.CredentialEmail, + AllowChange: true, + }) } register := &chatdb.Register{ @@ -240,10 +302,9 @@ func (o *chatSvr) AddUserAccount(ctx context.Context, req *chat.AddUserAccountRe AllowAddFriend: constant.DefaultAllowAddFriend, } - if err := o.Database.RegisterUser(ctx, register, account, attribute); err != nil { + if err := o.Database.RegisterUser(ctx, register, account, attribute, credentials); err != nil { return nil, err } - return &chat.AddUserAccountResp{}, nil } @@ -339,52 +400,42 @@ func (o *chatSvr) SearchUserInfo(ctx context.Context, req *chat.SearchUserInfoRe }, nil } -func (o *chatSvr) checkTheUniqueness(ctx context.Context, req *chat.AddUserAccountReq) error { +func (o *chatSvr) CheckUserExist(ctx context.Context, req *chat.CheckUserExistReq) (resp *chat.CheckUserExistResp, err error) { + if req.User == nil { + return nil, errs.ErrArgs.WrapMsg("user is nil") + } if req.User.PhoneNumber != "" { - _, err := o.Database.TakeAttributeByPhone(ctx, req.User.AreaCode, req.User.PhoneNumber) - if err == nil { - return eerrs.ErrPhoneAlreadyRegister.Wrap() - } else if !dbutil.IsDBNotFound(err) { - return err + account, err := o.Database.TakeCredentialByAccount(ctx, BuildCredentialPhone(req.User.AreaCode, req.User.PhoneNumber)) + // err != nil is not found User + if err != nil && !errors.Is(err, mongo.ErrNoDocuments) { + return nil, err } - } else { - _, err := o.Database.TakeAttributeByEmail(ctx, req.User.Email) - if err == nil { - return eerrs.ErrEmailAlreadyRegister.Wrap() - } else if !dbutil.IsDBNotFound(err) { - return err + if account != nil { + log.ZDebug(ctx, "Check Number is ", account.Account) + log.ZDebug(ctx, "Check userID is ", account.UserID) + return &chat.CheckUserExistResp{Userid: account.UserID, IsRegistered: true}, nil } } - return nil -} - -func (o *chatSvr) CheckUserExist(ctx context.Context, req *chat.CheckUserExistReq) (resp *chat.CheckUserExistResp, err error) { - if req.User.PhoneNumber != "" { - attributeByPhone, err := o.Database.TakeAttributeByPhone(ctx, req.User.AreaCode, req.User.PhoneNumber) - // err != nil is not found User - if err != nil && errs.Unwrap(err) != mongo.ErrNoDocuments { + if req.User.Email != "" { + account, err := o.Database.TakeCredentialByAccount(ctx, req.User.AreaCode) + if err != nil && !errors.Is(err, mongo.ErrNoDocuments) { return nil, err } - if attributeByPhone != nil { - log.ZDebug(ctx, "Check Number is ", attributeByPhone.PhoneNumber) - log.ZDebug(ctx, "Check userID is ", attributeByPhone.UserID) - if attributeByPhone.PhoneNumber == req.User.PhoneNumber { - return &chat.CheckUserExistResp{Userid: attributeByPhone.UserID, IsRegistered: true}, nil - } + if account != nil { + log.ZDebug(ctx, "Check email is ", account.Account) + log.ZDebug(ctx, "Check userID is ", account.UserID) + return &chat.CheckUserExistResp{Userid: account.UserID, IsRegistered: true}, nil } - } else { - if req.User.Email != "" { - attributeByEmail, err := o.Database.TakeAttributeByEmail(ctx, req.User.Email) - if err != nil && errs.Unwrap(err) != mongo.ErrNoDocuments { - return nil, err - } - if attributeByEmail != nil { - log.ZDebug(ctx, "Check email is ", attributeByEmail.Email) - log.ZDebug(ctx, "Check userID is ", attributeByEmail.UserID) - if attributeByEmail.Email == req.User.Email { - return &chat.CheckUserExistResp{Userid: attributeByEmail.UserID, IsRegistered: true}, nil - } - } + } + if req.User.Account != "" { + account, err := o.Database.TakeCredentialByAccount(ctx, req.User.Account) + if err != nil && !errors.Is(err, mongo.ErrNoDocuments) { + return nil, err + } + if account != nil { + log.ZDebug(ctx, "Check account is ", account.Account) + log.ZDebug(ctx, "Check userID is ", account.UserID) + return &chat.CheckUserExistResp{Userid: account.UserID, IsRegistered: true}, nil } } return nil, nil diff --git a/internal/rpc/chat/utils.go b/internal/rpc/chat/utils.go index 03a95d0df..b8c1f1740 100644 --- a/internal/rpc/chat/utils.go +++ b/internal/rpc/chat/utils.go @@ -1,26 +1,20 @@ -// Copyright © 2023 OpenIM open source community. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package chat import ( - "github.com/openimsdk/chat/pkg/common/db/table/chat" + "context" + "github.com/openimsdk/chat/pkg/common/db/dbutil" + table "github.com/openimsdk/chat/pkg/common/db/table/chat" + "github.com/openimsdk/chat/pkg/eerrs" + "github.com/openimsdk/chat/pkg/protocol/chat" "github.com/openimsdk/chat/pkg/protocol/common" + "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/utils/datautil" + "github.com/openimsdk/tools/utils/stringutil" + "strconv" + "strings" ) -func DbToPbAttribute(attribute *chat.Attribute) *common.UserPublicInfo { +func DbToPbAttribute(attribute *table.Attribute) *common.UserPublicInfo { if attribute == nil { return nil } @@ -35,11 +29,11 @@ func DbToPbAttribute(attribute *chat.Attribute) *common.UserPublicInfo { } } -func DbToPbAttributes(attributes []*chat.Attribute) []*common.UserPublicInfo { +func DbToPbAttributes(attributes []*table.Attribute) []*common.UserPublicInfo { return datautil.Slice(attributes, DbToPbAttribute) } -func DbToPbUserFullInfo(attribute *chat.Attribute) *common.UserFullInfo { +func DbToPbUserFullInfo(attribute *table.Attribute) *common.UserFullInfo { return &common.UserFullInfo{ UserID: attribute.UserID, Password: "", @@ -60,6 +54,59 @@ func DbToPbUserFullInfo(attribute *chat.Attribute) *common.UserFullInfo { } } -func DbToPbUserFullInfos(attributes []*chat.Attribute) []*common.UserFullInfo { +func DbToPbUserFullInfos(attributes []*table.Attribute) []*common.UserFullInfo { return datautil.Slice(attributes, DbToPbUserFullInfo) } + +func BuildCredentialPhone(areaCode, phone string) string { + return areaCode + " " + phone +} + +func (o *chatSvr) checkRegisterInfo(ctx context.Context, user *chat.RegisterUserInfo, isAdmin bool) error { + if user == nil { + return errs.ErrArgs.WrapMsg("user is nil") + } + if user.Email == "" && !(user.PhoneNumber != "" && user.AreaCode != "") && (!isAdmin || user.Account == "") { + return errs.ErrArgs.WrapMsg("at least one valid account is required") + } + if user.PhoneNumber != "" { + if !strings.HasPrefix(user.AreaCode, "+") { + user.AreaCode = "+" + user.AreaCode + } + if _, err := strconv.ParseUint(user.AreaCode[1:], 10, 64); err != nil { + return errs.ErrArgs.WrapMsg("area code must be number") + } + if _, err := strconv.ParseUint(user.PhoneNumber, 10, 64); err != nil { + return errs.ErrArgs.WrapMsg("phone number must be number") + } + _, err := o.Database.TakeAttributeByPhone(ctx, user.AreaCode, user.PhoneNumber) + if err == nil { + return eerrs.ErrPhoneAlreadyRegister.Wrap() + } else if !dbutil.IsDBNotFound(err) { + return err + } + } + if user.Account != "" { + if !stringutil.IsAlphanumeric(user.Account) { + return errs.ErrArgs.WrapMsg("account must be alphanumeric") + } + _, err := o.Database.TakeAttributeByAccount(ctx, user.Account) + if err == nil { + return eerrs.ErrAccountAlreadyRegister.Wrap() + } else if !dbutil.IsDBNotFound(err) { + return err + } + } + if user.Email != "" { + if !stringutil.IsValidEmail(user.Email) { + return errs.ErrArgs.WrapMsg("invalid email") + } + _, err := o.Database.TakeAttributeByAccount(ctx, user.Email) + if err == nil { + return eerrs.ErrAccountAlreadyRegister.Wrap() + } else if !dbutil.IsDBNotFound(err) { + return err + } + } + return nil +} diff --git a/pkg/common/config/config.go b/pkg/common/config/config.go index 76acd6c65..2348e9f0e 100644 --- a/pkg/common/config/config.go +++ b/pkg/common/config/config.go @@ -145,6 +145,7 @@ type Chat struct { Key string `mapstructure:"key"` Secret string `mapstructure:"secret"` } `mapstructure:"liveKit"` + AllowRegister bool `mapstructure:"allowRegister"` } type Admin struct { diff --git a/pkg/common/constant/constant.go b/pkg/common/constant/constant.go index ed2e77854..0c0acec5d 100644 --- a/pkg/common/constant/constant.go +++ b/pkg/common/constant/constant.go @@ -1,17 +1,3 @@ -// Copyright © 2023 OpenIM open source community. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package constant import "github.com/openimsdk/protocol/constant" @@ -108,6 +94,20 @@ const ( const CtxApiToken = "api-token" const ( - EmailRegister = 1 - PhoneRegister = 2 + AccountRegister = iota + EmailRegister + PhoneRegister +) + +const ( + GenderFemale = 0 // female + GenderMale = 1 // male + GenderUnknown = 2 // unknown +) + +// Credential Type +const ( + CredentialAccount = iota + CredentialPhone + CredentialEmail ) diff --git a/pkg/common/db/database/chat.go b/pkg/common/db/database/chat.go index e618845a4..55acd558a 100644 --- a/pkg/common/db/database/chat.go +++ b/pkg/common/db/database/chat.go @@ -31,26 +31,24 @@ import ( type ChatDatabaseInterface interface { GetUser(ctx context.Context, userID string) (account *chatdb.Account, err error) - UpdateUseInfo(ctx context.Context, userID string, attribute map[string]any) (err error) + UpdateUseInfo(ctx context.Context, userID string, attribute map[string]any, updateCred, delCred []*chatdb.Credential) (err error) FindAttribute(ctx context.Context, userIDs []string) ([]*chatdb.Attribute, error) FindAttributeByAccount(ctx context.Context, accounts []string) ([]*chatdb.Attribute, error) TakeAttributeByPhone(ctx context.Context, areaCode string, phoneNumber string) (*chatdb.Attribute, error) TakeAttributeByEmail(ctx context.Context, Email string) (*chatdb.Attribute, error) TakeAttributeByAccount(ctx context.Context, account string) (*chatdb.Attribute, error) TakeAttributeByUserID(ctx context.Context, userID string) (*chatdb.Attribute, error) + TakeAccount(ctx context.Context, userID string) (*chatdb.Account, error) + TakeCredentialByAccount(ctx context.Context, account string) (*chatdb.Credential, error) + TakeCredentialsByUserID(ctx context.Context, userID string) ([]*chatdb.Credential, error) + TakeLastVerifyCode(ctx context.Context, account string) (*chatdb.VerifyCode, error) Search(ctx context.Context, normalUser int32, keyword string, gender int32, pagination pagination.Pagination) (int64, []*chatdb.Attribute, error) SearchUser(ctx context.Context, keyword string, userIDs []string, genders []int32, pagination pagination.Pagination) (int64, []*chatdb.Attribute, error) CountVerifyCodeRange(ctx context.Context, account string, start time.Time, end time.Time) (int64, error) AddVerifyCode(ctx context.Context, verifyCode *chatdb.VerifyCode, fn func() error) error UpdateVerifyCodeIncrCount(ctx context.Context, id string) error - TakeLastVerifyCode(ctx context.Context, account string) (*chatdb.VerifyCode, error) DelVerifyCode(ctx context.Context, id string) error - RegisterUser(ctx context.Context, register *chatdb.Register, account *chatdb.Account, attribute *chatdb.Attribute) error - GetAccount(ctx context.Context, userID string) (*chatdb.Account, error) - GetAttribute(ctx context.Context, userID string) (*chatdb.Attribute, error) - GetAttributeByAccount(ctx context.Context, account string) (*chatdb.Attribute, error) - GetAttributeByPhone(ctx context.Context, areaCode string, phoneNumber string) (*chatdb.Attribute, error) - GetAttributeByEmail(ctx context.Context, email string) (*chatdb.Attribute, error) + RegisterUser(ctx context.Context, register *chatdb.Register, account *chatdb.Account, attribute *chatdb.Attribute, credentials []*chatdb.Credential) error LoginRecord(ctx context.Context, record *chatdb.UserLoginRecord, verifyCodeID *string) error UpdatePassword(ctx context.Context, userID string, password string) error UpdatePasswordAndDeleteVerifyCode(ctx context.Context, userID string, password string, codeID string) error @@ -73,6 +71,10 @@ func NewChatDatabase(cli *mongoutil.Client) (ChatDatabaseInterface, error) { if err != nil { return nil, err } + credential, err := chat.NewCredential(cli.GetDB()) + if err != nil { + return nil, err + } userLoginRecord, err := chat.NewUserLoginRecord(cli.GetDB()) if err != nil { return nil, err @@ -90,6 +92,7 @@ func NewChatDatabase(cli *mongoutil.Client) (ChatDatabaseInterface, error) { register: register, account: account, attribute: attribute, + credential: credential, userLoginRecord: userLoginRecord, verifyCode: verifyCode, forbiddenAccount: forbiddenAccount, @@ -101,6 +104,7 @@ type ChatDatabase struct { register chatdb.RegisterInterface account chatdb.AccountInterface attribute chatdb.AttributeInterface + credential chatdb.CredentialInterface userLoginRecord chatdb.UserLoginRecordInterface verifyCode chatdb.VerifyCodeInterface forbiddenAccount admin.ForbiddenAccountInterface @@ -110,8 +114,21 @@ func (o *ChatDatabase) GetUser(ctx context.Context, userID string) (account *cha return o.account.Take(ctx, userID) } -func (o *ChatDatabase) UpdateUseInfo(ctx context.Context, userID string, attribute map[string]any) (err error) { - return o.attribute.Update(ctx, userID, attribute) +func (o *ChatDatabase) UpdateUseInfo(ctx context.Context, userID string, attribute map[string]any, updateCred, delCred []*chatdb.Credential) (err error) { + return o.tx.Transaction(ctx, func(ctx context.Context) error { + if err = o.attribute.Update(ctx, userID, attribute); err != nil { + return err + } + for _, credential := range updateCred { + if err = o.credential.CreateOrUpdateAccount(ctx, credential); err != nil { + return err + } + } + if err = o.credential.DeleteByUserIDType(ctx, delCred...); err != nil { + return err + } + return nil + }) } func (o *ChatDatabase) FindAttribute(ctx context.Context, userIDs []string) ([]*chatdb.Attribute, error) { @@ -138,6 +155,22 @@ func (o *ChatDatabase) TakeAttributeByUserID(ctx context.Context, userID string) return o.attribute.Take(ctx, userID) } +func (o *ChatDatabase) TakeLastVerifyCode(ctx context.Context, account string) (*chatdb.VerifyCode, error) { + return o.verifyCode.TakeLast(ctx, account) +} + +func (o *ChatDatabase) TakeAccount(ctx context.Context, userID string) (*chatdb.Account, error) { + return o.account.Take(ctx, userID) +} + +func (o *ChatDatabase) TakeCredentialByAccount(ctx context.Context, account string) (*chatdb.Credential, error) { + return o.credential.TakeAccount(ctx, account) +} + +func (o *ChatDatabase) TakeCredentialsByUserID(ctx context.Context, userID string) ([]*chatdb.Credential, error) { + return o.credential.Find(ctx, userID) +} + func (o *ChatDatabase) Search(ctx context.Context, normalUser int32, keyword string, genders int32, pagination pagination.Pagination) (total int64, attributes []*chatdb.Attribute, err error) { var forbiddenIDs []string if int(normalUser) == constant.NormalUser { @@ -177,15 +210,11 @@ func (o *ChatDatabase) UpdateVerifyCodeIncrCount(ctx context.Context, id string) return o.verifyCode.Incr(ctx, id) } -func (o *ChatDatabase) TakeLastVerifyCode(ctx context.Context, account string) (*chatdb.VerifyCode, error) { - return o.verifyCode.TakeLast(ctx, account) -} - func (o *ChatDatabase) DelVerifyCode(ctx context.Context, id string) error { return o.verifyCode.Delete(ctx, id) } -func (o *ChatDatabase) RegisterUser(ctx context.Context, register *chatdb.Register, account *chatdb.Account, attribute *chatdb.Attribute) error { +func (o *ChatDatabase) RegisterUser(ctx context.Context, register *chatdb.Register, account *chatdb.Account, attribute *chatdb.Attribute, credentials []*chatdb.Credential) error { return o.tx.Transaction(ctx, func(ctx context.Context) error { if err := o.register.Create(ctx, register); err != nil { return err @@ -196,30 +225,13 @@ func (o *ChatDatabase) RegisterUser(ctx context.Context, register *chatdb.Regist if err := o.attribute.Create(ctx, attribute); err != nil { return err } + if err := o.credential.Create(ctx, credentials...); err != nil { + return err + } return nil }) } -func (o *ChatDatabase) GetAccount(ctx context.Context, userID string) (*chatdb.Account, error) { - return o.account.Take(ctx, userID) -} - -func (o *ChatDatabase) GetAttribute(ctx context.Context, userID string) (*chatdb.Attribute, error) { - return o.attribute.Take(ctx, userID) -} - -func (o *ChatDatabase) GetAttributeByAccount(ctx context.Context, account string) (*chatdb.Attribute, error) { - return o.attribute.TakeAccount(ctx, account) -} - -func (o *ChatDatabase) GetAttributeByPhone(ctx context.Context, areaCode string, phoneNumber string) (*chatdb.Attribute, error) { - return o.attribute.TakePhone(ctx, areaCode, phoneNumber) -} - -func (o *ChatDatabase) GetAttributeByEmail(ctx context.Context, email string) (*chatdb.Attribute, error) { - return o.attribute.TakeEmail(ctx, email) -} - func (o *ChatDatabase) LoginRecord(ctx context.Context, record *chatdb.UserLoginRecord, verifyCodeID *string) error { return o.tx.Transaction(ctx, func(ctx context.Context) error { if err := o.userLoginRecord.Create(ctx, record); err != nil { diff --git a/pkg/common/db/model/chat/credential.go b/pkg/common/db/model/chat/credential.go new file mode 100644 index 000000000..7564c45ef --- /dev/null +++ b/pkg/common/db/model/chat/credential.go @@ -0,0 +1,142 @@ +package chat + +import ( + "context" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/openimsdk/chat/pkg/common/db/table/chat" + "github.com/openimsdk/tools/db/mongoutil" + "github.com/openimsdk/tools/db/pagination" + "github.com/openimsdk/tools/errs" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +func NewCredential(db *mongo.Database) (chat.CredentialInterface, error) { + coll := db.Collection("credential") + _, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{ + { + Keys: bson.D{ + {Key: "user_id", Value: 1}, + {Key: "type", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }, + { + Keys: bson.D{ + {Key: "account", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }, + }) + if err != nil { + return nil, errs.Wrap(err) + } + return &Credential{coll: coll}, nil +} + +type Credential struct { + coll *mongo.Collection +} + +func (o *Credential) Create(ctx context.Context, credential ...*chat.Credential) error { + return mongoutil.InsertMany(ctx, o.coll, credential) +} + +func (o *Credential) CreateOrUpdateAccount(ctx context.Context, credential *chat.Credential) error { + return mongoutil.UpdateOne(ctx, o.coll, bson.M{ + "user_id": credential.UserID, + "type": credential.Type, + }, bson.M{ + "$set": bson.M{ + "account": credential.Account, + }, + "$setOnInsert": bson.M{ + "user_id": credential.UserID, + "type": credential.Type, + "allow_change": credential.AllowChange, + }, + }, false, options.Update().SetUpsert(true)) +} + +func (o *Credential) Update(ctx context.Context, userID string, data map[string]any) error { + if len(data) == 0 { + return nil + } + return mongoutil.UpdateOne(ctx, o.coll, bson.M{"user_id": userID}, bson.M{"$set": data}, false) +} + +func (o *Credential) Find(ctx context.Context, userID string) ([]*chat.Credential, error) { + return mongoutil.Find[*chat.Credential](ctx, o.coll, bson.M{"user_id": userID}) +} + +func (o *Credential) FindAccount(ctx context.Context, accounts []string) ([]*chat.Credential, error) { + return mongoutil.Find[*chat.Credential](ctx, o.coll, bson.M{"account": bson.M{"$in": accounts}}) +} + +func (o *Credential) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*chat.Credential, error) { + return o.SearchUser(ctx, keyword, nil, pagination) +} + +func (o *Credential) TakeAccount(ctx context.Context, account string) (*chat.Credential, error) { + return mongoutil.FindOne[*chat.Credential](ctx, o.coll, bson.M{"account": account}) +} + +func (o *Credential) Take(ctx context.Context, userID string) (*chat.Credential, error) { + return mongoutil.FindOne[*chat.Credential](ctx, o.coll, bson.M{"user_id": userID}) +} + +func (o *Credential) SearchNormalUser(ctx context.Context, keyword string, forbiddenIDs []string, pagination pagination.Pagination) (int64, []*chat.Credential, error) { + filter := bson.M{} + + if len(forbiddenIDs) > 0 { + filter["user_id"] = bson.M{ + "$nin": forbiddenIDs, + } + } + if keyword != "" { + filter["$or"] = []bson.M{ + {"user_id": bson.M{"$regex": keyword, "$options": "i"}}, + {"account": bson.M{"$regex": keyword, "$options": "i"}}, + } + } + return mongoutil.FindPage[*chat.Credential](ctx, o.coll, filter, pagination) +} + +func (o *Credential) SearchUser(ctx context.Context, keyword string, userIDs []string, pagination pagination.Pagination) (int64, []*chat.Credential, error) { + filter := bson.M{} + + if len(userIDs) > 0 { + filter["user_id"] = bson.M{ + "$in": userIDs, + } + } + if keyword != "" { + filter["$or"] = []bson.M{ + {"user_id": bson.M{"$regex": keyword, "$options": "i"}}, + {"account": bson.M{"$regex": keyword, "$options": "i"}}, + } + } + return mongoutil.FindPage[*chat.Credential](ctx, o.coll, filter, pagination) +} + +func (o *Credential) Delete(ctx context.Context, userIDs []string) error { + if len(userIDs) == 0 { + return nil + } + return mongoutil.DeleteMany(ctx, o.coll, bson.M{"user_id": bson.M{"$in": userIDs}}) +} + +func (o *Credential) DeleteByUserIDType(ctx context.Context, credentials ...*chat.Credential) error { + var filters []bson.M + for _, credential := range credentials { + filters = append(filters, bson.M{ + "user_id": credential.UserID, + "type": credential.Type, + }) + } + + query := bson.M{"$or": filters} + + return mongoutil.DeleteMany(ctx, o.coll, query) +} diff --git a/pkg/common/db/table/chat/attribute.go b/pkg/common/db/table/chat/attribute.go index d77f06176..4e033ba16 100644 --- a/pkg/common/db/table/chat/attribute.go +++ b/pkg/common/db/table/chat/attribute.go @@ -1,17 +1,3 @@ -// Copyright © 2023 OpenIM open source community. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package chat import ( diff --git a/pkg/common/db/table/chat/credential.go b/pkg/common/db/table/chat/credential.go new file mode 100644 index 000000000..e4d23d6c8 --- /dev/null +++ b/pkg/common/db/table/chat/credential.go @@ -0,0 +1,32 @@ +package chat + +import ( + "context" + "github.com/openimsdk/tools/db/pagination" +) + +type Credential struct { + UserID string `bson:"user_id"` + Account string `bson:"account"` + Type int `bson:"type"` // 1:phone;2:email + AllowChange bool `bson:"allow_change"` +} + +func (Credential) TableName() string { + return "credentials" +} + +type CredentialInterface interface { + Create(ctx context.Context, credential ...*Credential) error + CreateOrUpdateAccount(ctx context.Context, credential *Credential) error + Update(ctx context.Context, userID string, data map[string]any) error + Find(ctx context.Context, userID string) ([]*Credential, error) + FindAccount(ctx context.Context, accounts []string) ([]*Credential, error) + Search(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*Credential, error) + TakeAccount(ctx context.Context, account string) (*Credential, error) + Take(ctx context.Context, userID string) (*Credential, error) + SearchNormalUser(ctx context.Context, keyword string, forbiddenID []string, pagination pagination.Pagination) (int64, []*Credential, error) + SearchUser(ctx context.Context, keyword string, userIDs []string, pagination pagination.Pagination) (int64, []*Credential, error) + Delete(ctx context.Context, userIDs []string) error + DeleteByUserIDType(ctx context.Context, credentials ...*Credential) error +} diff --git a/pkg/common/imapi/caller.go b/pkg/common/imapi/caller.go index 0a3923cb2..24b9d545d 100644 --- a/pkg/common/imapi/caller.go +++ b/pkg/common/imapi/caller.go @@ -1,17 +1,3 @@ -// Copyright © 2023 OpenIM open source community. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package imapi import ( diff --git a/pkg/email/mail_test.go b/pkg/email/mail_test.go index c6824510a..0f9ebe348 100644 --- a/pkg/email/mail_test.go +++ b/pkg/email/mail_test.go @@ -1,77 +1,51 @@ -// Copyright © 2023 OpenIM open source community. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package email -import ( - "context" - "errors" - "fmt" - "io/ioutil" - "os" - "testing" - - "github.com/openimsdk/chat/pkg/common/config" - "gopkg.in/yaml.v3" -) - -func TestEmail(T *testing.T) { - if err := InitConfig(); err != nil { - fmt.Fprintf(os.Stderr, "\n\nexit -1: \n%+v\n\n", err) - os.Exit(-1) - } - tests := []struct { - name string - ctx context.Context - mail string - code string - want error - }{ - { - name: "success send email", - ctx: context.Background(), - mail: "test@gmail.com", - code: "5555", - want: errors.New("nil"), - }, - { - name: "fail send email", - ctx: context.Background(), - mail: "", - code: "5555", - want: errors.New("dial tcp :0: connectex: The requested address is not valid in its context."), - }, - } - mail := NewMail() - - for _, tt := range tests { - T.Run(tt.name, func(t *testing.T) { - if got := mail.SendMail(tt.ctx, tt.mail, tt.code); errors.Is(got, tt.want) { - t.Errorf("%v have a err,%v", tt.name, tt.want) - } - }) - } -} - -func InitConfig() error { - yam, err := ioutil.ReadFile("../../config/config.yaml") - if err != nil { - return err - } - err = yaml.Unmarshal(yam, &config.Config) - if err != nil { - return err - } - return nil -} +//func TestEmail(T *testing.T) { +// if err := InitConfig(); err != nil { +// fmt.Fprintf(os.Stderr, "\n\nexit -1: \n%+v\n\n", err) +// os.Exit(-1) +// } +// tests := []struct { +// name string +// ctx context.Context +// mail string +// code string +// want error +// }{ +// { +// name: "success send email", +// ctx: context.Background(), +// mail: "test@gmail.com", +// code: "5555", +// want: errors.New("nil"), +// }, +// { +// name: "fail send email", +// ctx: context.Background(), +// mail: "", +// code: "5555", +// want: errors.New("dial tcp :0: connectex: The requested address is not valid in its context."), +// }, +// } +// mail := NewMail() +// +// for _, tt := range tests { +// T.Run(tt.name, func(t *testing.T) { +// if got := mail.SendMail(tt.ctx, tt.mail, tt.code); errors.Is(got, tt.want) { +// t.Errorf("%v have a err,%v", tt.name, tt.want) +// } +// }) +// } +//} +// +//func InitConfig() error { +// yam, err := ioutil.ReadFile("../../config/config.yaml") +// if err != nil { +// return err +// } +// err = yaml.Unmarshal(yam, &config.Config) +// if err != nil { +// return err +// } +// return nil +//} diff --git a/pkg/protocol/chat/chat.pb.go b/pkg/protocol/chat/chat.pb.go index 992e9b2e5..b5a68d7ca 100644 --- a/pkg/protocol/chat/chat.pb.go +++ b/pkg/protocol/chat/chat.pb.go @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.33.0 -// protoc v5.27.1 +// protoc v5.26.0 // source: chat/chat.proto package chat @@ -2767,6 +2767,176 @@ func (*DelUserAccountResp) Descriptor() ([]byte, []int) { return file_chat_chat_proto_rawDescGZIP(), []int{42} } +type SetAllowRegisterReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AllowRegister bool `protobuf:"varint,1,opt,name=allowRegister,proto3" json:"allowRegister"` +} + +func (x *SetAllowRegisterReq) Reset() { + *x = SetAllowRegisterReq{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_chat_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetAllowRegisterReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetAllowRegisterReq) ProtoMessage() {} + +func (x *SetAllowRegisterReq) ProtoReflect() protoreflect.Message { + mi := &file_chat_chat_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetAllowRegisterReq.ProtoReflect.Descriptor instead. +func (*SetAllowRegisterReq) Descriptor() ([]byte, []int) { + return file_chat_chat_proto_rawDescGZIP(), []int{43} +} + +func (x *SetAllowRegisterReq) GetAllowRegister() bool { + if x != nil { + return x.AllowRegister + } + return false +} + +type SetAllowRegisterResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SetAllowRegisterResp) Reset() { + *x = SetAllowRegisterResp{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_chat_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetAllowRegisterResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetAllowRegisterResp) ProtoMessage() {} + +func (x *SetAllowRegisterResp) ProtoReflect() protoreflect.Message { + mi := &file_chat_chat_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetAllowRegisterResp.ProtoReflect.Descriptor instead. +func (*SetAllowRegisterResp) Descriptor() ([]byte, []int) { + return file_chat_chat_proto_rawDescGZIP(), []int{44} +} + +type GetAllowRegisterReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetAllowRegisterReq) Reset() { + *x = GetAllowRegisterReq{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_chat_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllowRegisterReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllowRegisterReq) ProtoMessage() {} + +func (x *GetAllowRegisterReq) ProtoReflect() protoreflect.Message { + mi := &file_chat_chat_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllowRegisterReq.ProtoReflect.Descriptor instead. +func (*GetAllowRegisterReq) Descriptor() ([]byte, []int) { + return file_chat_chat_proto_rawDescGZIP(), []int{45} +} + +type GetAllowRegisterResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AllowRegister bool `protobuf:"varint,1,opt,name=allowRegister,proto3" json:"allowRegister"` +} + +func (x *GetAllowRegisterResp) Reset() { + *x = GetAllowRegisterResp{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_chat_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllowRegisterResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllowRegisterResp) ProtoMessage() {} + +func (x *GetAllowRegisterResp) ProtoReflect() protoreflect.Message { + mi := &file_chat_chat_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllowRegisterResp.ProtoReflect.Descriptor instead. +func (*GetAllowRegisterResp) Descriptor() ([]byte, []int) { + return file_chat_chat_proto_rawDescGZIP(), []int{46} +} + +func (x *GetAllowRegisterResp) GetAllowRegister() bool { + if x != nil { + return x.AllowRegister + } + return false +} + var File_chat_chat_proto protoreflect.FileDescriptor var file_chat_chat_proto_rawDesc = []byte{ @@ -3136,117 +3306,138 @@ var file_chat_chat_proto_rawDesc = []byte{ 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x32, 0xa3, 0x0d, 0x0a, 0x04, 0x63, 0x68, 0x61, 0x74, 0x12, 0x51, - 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, - 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, - 0x74, 0x2e, 0x41, 0x64, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, - 0x74, 0x2e, 0x41, 0x64, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x12, 0x63, 0x0a, 0x14, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, - 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x2e, 0x6f, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x3b, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x6f, + 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x24, 0x0a, 0x0d, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x22, 0x16, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x15, 0x0a, 0x13, 0x47, 0x65, + 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x22, 0x3c, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x32, + 0xd5, 0x0e, 0x0a, 0x04, 0x63, 0x68, 0x61, 0x74, 0x12, 0x51, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x41, + 0x64, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1e, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x41, 0x64, 0x64, 0x55, + 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x41, 0x64, 0x64, 0x55, + 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x63, + 0x0a, 0x14, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, + 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x71, 0x1a, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, - 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x5d, 0x0a, 0x12, 0x46, 0x69, 0x6e, - 0x64, 0x55, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, - 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x71, 0x1a, 0x23, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, - 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x71, 0x1a, 0x23, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, - 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x57, 0x0a, 0x10, 0x46, 0x69, 0x6e, 0x64, 0x55, - 0x73, 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, - 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x21, 0x2e, + 0x65, 0x73, 0x70, 0x12, 0x5d, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x23, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, - 0x55, 0x73, 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, - 0x12, 0x51, 0x0a, 0x0e, 0x53, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, - 0x64, 0x65, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, - 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x52, - 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, - 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x12, 0x45, 0x0a, 0x0a, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, - 0x65, 0x12, 0x1a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x56, 0x65, 0x72, 0x69, - 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x4b, 0x0a, 0x0c, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, - 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x36, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x12, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x4c, - 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, - 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, - 0x4e, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x12, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x52, - 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, - 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x52, 0x65, - 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, - 0x51, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x73, 0x70, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, + 0x46, 0x75, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, + 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, + 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x23, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x55, 0x73, 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x70, 0x12, 0x57, 0x0a, 0x10, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x46, 0x75, 0x6c, + 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, + 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x21, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, + 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x46, 0x75, + 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x53, 0x65, + 0x6e, 0x64, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1e, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x56, + 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x56, + 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x45, 0x0a, + 0x0a, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, + 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x12, 0x4b, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, + 0x61, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, + 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x12, 0x36, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x15, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, + 0x71, 0x1a, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x4e, 0x0a, 0x0d, 0x52, 0x65, 0x73, + 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1d, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1e, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x69, 0x73, 0x74, 0x12, 0x1e, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1f, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, + 0x51, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, + 0x44, 0x65, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x45, - 0x78, 0x69, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, - 0x61, 0x74, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, - 0x61, 0x74, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x55, 0x73, 0x65, 0x72, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, - 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, - 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, + 0x44, 0x65, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x12, 0x54, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, + 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, + 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x54, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, - 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, - 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, - 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x54, - 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, - 0x72, 0x12, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, - 0x46, 0x69, 0x6e, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, - 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x6e, 0x49, 0x4d, 0x43, 0x61, - 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, - 0x63, 0x68, 0x61, 0x74, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x49, 0x4d, 0x43, 0x61, 0x6c, 0x6c, 0x62, - 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, - 0x63, 0x68, 0x61, 0x74, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x49, 0x4d, 0x43, 0x61, 0x6c, 0x6c, 0x62, - 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4c, - 0x6f, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, - 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, - 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x53, 0x65, - 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6c, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x6f, 0x72, 0x56, 0x69, 0x64, 0x65, - 0x6f, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, - 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, - 0x6f, 0x72, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x71, 0x1a, 0x28, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, - 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x6f, 0x72, 0x56, 0x69, 0x64, 0x65, 0x6f, - 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x42, 0x2d, 0x5a, 0x2b, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, - 0x73, 0x64, 0x6b, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, + 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x6e, 0x49, 0x4d, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x4f, + 0x70, 0x65, 0x6e, 0x49, 0x4d, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, + 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x4f, + 0x70, 0x65, 0x6e, 0x49, 0x4d, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, + 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, + 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x12, 0x51, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, + 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, + 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x46, 0x6f, 0x72, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x65, 0x74, 0x69, + 0x6e, 0x67, 0x12, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x6f, 0x72, 0x56, 0x69, 0x64, 0x65, + 0x6f, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x28, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x46, 0x6f, 0x72, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x12, 0x57, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x6f, + 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x21, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x6c, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x57, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x12, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, 0x61, 0x74, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x1a, 0x21, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x2e, 0x63, 0x68, + 0x61, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6d, 0x73, 0x64, 0x6b, 0x2f, + 0x63, 0x68, 0x61, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3261,7 +3452,7 @@ func file_chat_chat_proto_rawDescGZIP() []byte { return file_chat_chat_proto_rawDescData } -var file_chat_chat_proto_msgTypes = make([]protoimpl.MessageInfo, 46) +var file_chat_chat_proto_msgTypes = make([]protoimpl.MessageInfo, 50) var file_chat_chat_proto_goTypes = []interface{}{ (*UserIdentity)(nil), // 0: openim.chat.UserIdentity (*UpdateUserInfoReq)(nil), // 1: openim.chat.UpdateUserInfoReq @@ -3306,45 +3497,49 @@ var file_chat_chat_proto_goTypes = []interface{}{ (*CheckUserExistResp)(nil), // 40: openim.chat.CheckUserExistResp (*DelUserAccountReq)(nil), // 41: openim.chat.DelUserAccountReq (*DelUserAccountResp)(nil), // 42: openim.chat.DelUserAccountResp - nil, // 43: openim.chat.FindUserAccountResp.UserAccountMapEntry - nil, // 44: openim.chat.FindAccountUserResp.AccountUserMapEntry - nil, // 45: openim.chat.UserLoginCountResp.CountEntry - (*wrapperspb.StringValue)(nil), // 46: openim.protobuf.StringValue - (*wrapperspb.Int32Value)(nil), // 47: openim.protobuf.Int32Value - (*wrapperspb.Int64Value)(nil), // 48: openim.protobuf.Int64Value - (*common.UserPublicInfo)(nil), // 49: openim.chat.common.UserPublicInfo - (*sdkws.RequestPagination)(nil), // 50: openim.sdkws.RequestPagination - (*common.UserFullInfo)(nil), // 51: openim.chat.common.UserFullInfo + (*SetAllowRegisterReq)(nil), // 43: openim.chat.SetAllowRegisterReq + (*SetAllowRegisterResp)(nil), // 44: openim.chat.SetAllowRegisterResp + (*GetAllowRegisterReq)(nil), // 45: openim.chat.GetAllowRegisterReq + (*GetAllowRegisterResp)(nil), // 46: openim.chat.GetAllowRegisterResp + nil, // 47: openim.chat.FindUserAccountResp.UserAccountMapEntry + nil, // 48: openim.chat.FindAccountUserResp.AccountUserMapEntry + nil, // 49: openim.chat.UserLoginCountResp.CountEntry + (*wrapperspb.StringValue)(nil), // 50: openim.protobuf.StringValue + (*wrapperspb.Int32Value)(nil), // 51: openim.protobuf.Int32Value + (*wrapperspb.Int64Value)(nil), // 52: openim.protobuf.Int64Value + (*common.UserPublicInfo)(nil), // 53: openim.chat.common.UserPublicInfo + (*sdkws.RequestPagination)(nil), // 54: openim.sdkws.RequestPagination + (*common.UserFullInfo)(nil), // 55: openim.chat.common.UserFullInfo } var file_chat_chat_proto_depIdxs = []int32{ - 46, // 0: openim.chat.UpdateUserInfoReq.account:type_name -> openim.protobuf.StringValue - 46, // 1: openim.chat.UpdateUserInfoReq.phoneNumber:type_name -> openim.protobuf.StringValue - 46, // 2: openim.chat.UpdateUserInfoReq.areaCode:type_name -> openim.protobuf.StringValue - 46, // 3: openim.chat.UpdateUserInfoReq.email:type_name -> openim.protobuf.StringValue - 46, // 4: openim.chat.UpdateUserInfoReq.nickname:type_name -> openim.protobuf.StringValue - 46, // 5: openim.chat.UpdateUserInfoReq.faceURL:type_name -> openim.protobuf.StringValue - 47, // 6: openim.chat.UpdateUserInfoReq.gender:type_name -> openim.protobuf.Int32Value - 47, // 7: openim.chat.UpdateUserInfoReq.level:type_name -> openim.protobuf.Int32Value - 48, // 8: openim.chat.UpdateUserInfoReq.birth:type_name -> openim.protobuf.Int64Value - 47, // 9: openim.chat.UpdateUserInfoReq.allowAddFriend:type_name -> openim.protobuf.Int32Value - 47, // 10: openim.chat.UpdateUserInfoReq.allowBeep:type_name -> openim.protobuf.Int32Value - 47, // 11: openim.chat.UpdateUserInfoReq.allowVibration:type_name -> openim.protobuf.Int32Value - 47, // 12: openim.chat.UpdateUserInfoReq.globalRecvMsgOpt:type_name -> openim.protobuf.Int32Value - 47, // 13: openim.chat.UpdateUserInfoReq.RegisterType:type_name -> openim.protobuf.Int32Value - 49, // 14: openim.chat.FindUserPublicInfoResp.users:type_name -> openim.chat.common.UserPublicInfo - 50, // 15: openim.chat.SearchUserPublicInfoReq.pagination:type_name -> openim.sdkws.RequestPagination - 49, // 16: openim.chat.SearchUserPublicInfoResp.users:type_name -> openim.chat.common.UserPublicInfo - 51, // 17: openim.chat.FindUserFullInfoResp.users:type_name -> openim.chat.common.UserFullInfo + 50, // 0: openim.chat.UpdateUserInfoReq.account:type_name -> openim.protobuf.StringValue + 50, // 1: openim.chat.UpdateUserInfoReq.phoneNumber:type_name -> openim.protobuf.StringValue + 50, // 2: openim.chat.UpdateUserInfoReq.areaCode:type_name -> openim.protobuf.StringValue + 50, // 3: openim.chat.UpdateUserInfoReq.email:type_name -> openim.protobuf.StringValue + 50, // 4: openim.chat.UpdateUserInfoReq.nickname:type_name -> openim.protobuf.StringValue + 50, // 5: openim.chat.UpdateUserInfoReq.faceURL:type_name -> openim.protobuf.StringValue + 51, // 6: openim.chat.UpdateUserInfoReq.gender:type_name -> openim.protobuf.Int32Value + 51, // 7: openim.chat.UpdateUserInfoReq.level:type_name -> openim.protobuf.Int32Value + 52, // 8: openim.chat.UpdateUserInfoReq.birth:type_name -> openim.protobuf.Int64Value + 51, // 9: openim.chat.UpdateUserInfoReq.allowAddFriend:type_name -> openim.protobuf.Int32Value + 51, // 10: openim.chat.UpdateUserInfoReq.allowBeep:type_name -> openim.protobuf.Int32Value + 51, // 11: openim.chat.UpdateUserInfoReq.allowVibration:type_name -> openim.protobuf.Int32Value + 51, // 12: openim.chat.UpdateUserInfoReq.globalRecvMsgOpt:type_name -> openim.protobuf.Int32Value + 51, // 13: openim.chat.UpdateUserInfoReq.RegisterType:type_name -> openim.protobuf.Int32Value + 53, // 14: openim.chat.FindUserPublicInfoResp.users:type_name -> openim.chat.common.UserPublicInfo + 54, // 15: openim.chat.SearchUserPublicInfoReq.pagination:type_name -> openim.sdkws.RequestPagination + 53, // 16: openim.chat.SearchUserPublicInfoResp.users:type_name -> openim.chat.common.UserPublicInfo + 55, // 17: openim.chat.FindUserFullInfoResp.users:type_name -> openim.chat.common.UserFullInfo 13, // 18: openim.chat.RegisterUserReq.user:type_name -> openim.chat.RegisterUserInfo 13, // 19: openim.chat.AddUserAccountReq.user:type_name -> openim.chat.RegisterUserInfo - 43, // 20: openim.chat.FindUserAccountResp.userAccountMap:type_name -> openim.chat.FindUserAccountResp.UserAccountMapEntry - 44, // 21: openim.chat.FindAccountUserResp.accountUserMap:type_name -> openim.chat.FindAccountUserResp.AccountUserMapEntry - 49, // 22: openim.chat.SignalRecord.inviterUserList:type_name -> openim.chat.common.UserPublicInfo - 50, // 23: openim.chat.SearchUserFullInfoReq.pagination:type_name -> openim.sdkws.RequestPagination - 51, // 24: openim.chat.SearchUserFullInfoResp.users:type_name -> openim.chat.common.UserFullInfo - 45, // 25: openim.chat.UserLoginCountResp.count:type_name -> openim.chat.UserLoginCountResp.CountEntry - 50, // 26: openim.chat.SearchUserInfoReq.pagination:type_name -> openim.sdkws.RequestPagination - 51, // 27: openim.chat.SearchUserInfoResp.users:type_name -> openim.chat.common.UserFullInfo + 47, // 20: openim.chat.FindUserAccountResp.userAccountMap:type_name -> openim.chat.FindUserAccountResp.UserAccountMapEntry + 48, // 21: openim.chat.FindAccountUserResp.accountUserMap:type_name -> openim.chat.FindAccountUserResp.AccountUserMapEntry + 53, // 22: openim.chat.SignalRecord.inviterUserList:type_name -> openim.chat.common.UserPublicInfo + 54, // 23: openim.chat.SearchUserFullInfoReq.pagination:type_name -> openim.sdkws.RequestPagination + 55, // 24: openim.chat.SearchUserFullInfoResp.users:type_name -> openim.chat.common.UserFullInfo + 49, // 25: openim.chat.UserLoginCountResp.count:type_name -> openim.chat.UserLoginCountResp.CountEntry + 54, // 26: openim.chat.SearchUserInfoReq.pagination:type_name -> openim.sdkws.RequestPagination + 55, // 27: openim.chat.SearchUserInfoResp.users:type_name -> openim.chat.common.UserFullInfo 13, // 28: openim.chat.CheckUserExistReq.user:type_name -> openim.chat.RegisterUserInfo 1, // 29: openim.chat.chat.UpdateUserInfo:input_type -> openim.chat.UpdateUserInfoReq 16, // 30: openim.chat.chat.AddUserAccount:input_type -> openim.chat.AddUserAccountReq @@ -3366,28 +3561,32 @@ var file_chat_chat_proto_depIdxs = []int32{ 32, // 46: openim.chat.chat.UserLoginCount:input_type -> openim.chat.UserLoginCountReq 35, // 47: openim.chat.chat.SearchUserInfo:input_type -> openim.chat.SearchUserInfoReq 37, // 48: openim.chat.chat.GetTokenForVideoMeeting:input_type -> openim.chat.GetTokenForVideoMeetingReq - 2, // 49: openim.chat.chat.UpdateUserInfo:output_type -> openim.chat.UpdateUserInfoResp - 17, // 50: openim.chat.chat.AddUserAccount:output_type -> openim.chat.AddUserAccountResp - 6, // 51: openim.chat.chat.SearchUserPublicInfo:output_type -> openim.chat.SearchUserPublicInfoResp - 4, // 52: openim.chat.chat.FindUserPublicInfo:output_type -> openim.chat.FindUserPublicInfoResp - 31, // 53: openim.chat.chat.SearchUserFullInfo:output_type -> openim.chat.SearchUserFullInfoResp - 8, // 54: openim.chat.chat.FindUserFullInfo:output_type -> openim.chat.FindUserFullInfoResp - 10, // 55: openim.chat.chat.SendVerifyCode:output_type -> openim.chat.SendVerifyCodeResp - 12, // 56: openim.chat.chat.VerifyCode:output_type -> openim.chat.VerifyCodeResp - 15, // 57: openim.chat.chat.RegisterUser:output_type -> openim.chat.RegisterUserResp - 34, // 58: openim.chat.chat.Login:output_type -> openim.chat.LoginResp - 20, // 59: openim.chat.chat.ResetPassword:output_type -> openim.chat.ResetPasswordResp - 22, // 60: openim.chat.chat.ChangePassword:output_type -> openim.chat.ChangePasswordResp - 40, // 61: openim.chat.chat.CheckUserExist:output_type -> openim.chat.CheckUserExistResp - 42, // 62: openim.chat.chat.DelUserAccount:output_type -> openim.chat.DelUserAccountResp - 24, // 63: openim.chat.chat.FindUserAccount:output_type -> openim.chat.FindUserAccountResp - 26, // 64: openim.chat.chat.FindAccountUser:output_type -> openim.chat.FindAccountUserResp - 29, // 65: openim.chat.chat.OpenIMCallback:output_type -> openim.chat.OpenIMCallbackResp - 33, // 66: openim.chat.chat.UserLoginCount:output_type -> openim.chat.UserLoginCountResp - 36, // 67: openim.chat.chat.SearchUserInfo:output_type -> openim.chat.SearchUserInfoResp - 38, // 68: openim.chat.chat.GetTokenForVideoMeeting:output_type -> openim.chat.GetTokenForVideoMeetingResp - 49, // [49:69] is the sub-list for method output_type - 29, // [29:49] is the sub-list for method input_type + 43, // 49: openim.chat.chat.SetAllowRegister:input_type -> openim.chat.SetAllowRegisterReq + 45, // 50: openim.chat.chat.GetAllowRegister:input_type -> openim.chat.GetAllowRegisterReq + 2, // 51: openim.chat.chat.UpdateUserInfo:output_type -> openim.chat.UpdateUserInfoResp + 17, // 52: openim.chat.chat.AddUserAccount:output_type -> openim.chat.AddUserAccountResp + 6, // 53: openim.chat.chat.SearchUserPublicInfo:output_type -> openim.chat.SearchUserPublicInfoResp + 4, // 54: openim.chat.chat.FindUserPublicInfo:output_type -> openim.chat.FindUserPublicInfoResp + 31, // 55: openim.chat.chat.SearchUserFullInfo:output_type -> openim.chat.SearchUserFullInfoResp + 8, // 56: openim.chat.chat.FindUserFullInfo:output_type -> openim.chat.FindUserFullInfoResp + 10, // 57: openim.chat.chat.SendVerifyCode:output_type -> openim.chat.SendVerifyCodeResp + 12, // 58: openim.chat.chat.VerifyCode:output_type -> openim.chat.VerifyCodeResp + 15, // 59: openim.chat.chat.RegisterUser:output_type -> openim.chat.RegisterUserResp + 34, // 60: openim.chat.chat.Login:output_type -> openim.chat.LoginResp + 20, // 61: openim.chat.chat.ResetPassword:output_type -> openim.chat.ResetPasswordResp + 22, // 62: openim.chat.chat.ChangePassword:output_type -> openim.chat.ChangePasswordResp + 40, // 63: openim.chat.chat.CheckUserExist:output_type -> openim.chat.CheckUserExistResp + 42, // 64: openim.chat.chat.DelUserAccount:output_type -> openim.chat.DelUserAccountResp + 24, // 65: openim.chat.chat.FindUserAccount:output_type -> openim.chat.FindUserAccountResp + 26, // 66: openim.chat.chat.FindAccountUser:output_type -> openim.chat.FindAccountUserResp + 29, // 67: openim.chat.chat.OpenIMCallback:output_type -> openim.chat.OpenIMCallbackResp + 33, // 68: openim.chat.chat.UserLoginCount:output_type -> openim.chat.UserLoginCountResp + 36, // 69: openim.chat.chat.SearchUserInfo:output_type -> openim.chat.SearchUserInfoResp + 38, // 70: openim.chat.chat.GetTokenForVideoMeeting:output_type -> openim.chat.GetTokenForVideoMeetingResp + 44, // 71: openim.chat.chat.SetAllowRegister:output_type -> openim.chat.SetAllowRegisterResp + 46, // 72: openim.chat.chat.GetAllowRegister:output_type -> openim.chat.GetAllowRegisterResp + 51, // [51:73] is the sub-list for method output_type + 29, // [29:51] is the sub-list for method input_type 29, // [29:29] is the sub-list for extension type_name 29, // [29:29] is the sub-list for extension extendee 0, // [0:29] is the sub-list for field type_name @@ -3915,6 +4114,54 @@ func file_chat_chat_proto_init() { return nil } } + file_chat_chat_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetAllowRegisterReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_chat_chat_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetAllowRegisterResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_chat_chat_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllowRegisterReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_chat_chat_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllowRegisterResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -3922,7 +4169,7 @@ func file_chat_chat_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_chat_chat_proto_rawDesc, NumEnums: 0, - NumMessages: 46, + NumMessages: 50, NumExtensions: 0, NumServices: 1, }, @@ -3973,6 +4220,8 @@ type ChatClient interface { SearchUserInfo(ctx context.Context, in *SearchUserInfoReq, opts ...grpc.CallOption) (*SearchUserInfoResp, error) // Audio/video call and video meeting GetTokenForVideoMeeting(ctx context.Context, in *GetTokenForVideoMeetingReq, opts ...grpc.CallOption) (*GetTokenForVideoMeetingResp, error) + SetAllowRegister(ctx context.Context, in *SetAllowRegisterReq, opts ...grpc.CallOption) (*SetAllowRegisterResp, error) + GetAllowRegister(ctx context.Context, in *GetAllowRegisterReq, opts ...grpc.CallOption) (*GetAllowRegisterResp, error) } type chatClient struct { @@ -4163,6 +4412,24 @@ func (c *chatClient) GetTokenForVideoMeeting(ctx context.Context, in *GetTokenFo return out, nil } +func (c *chatClient) SetAllowRegister(ctx context.Context, in *SetAllowRegisterReq, opts ...grpc.CallOption) (*SetAllowRegisterResp, error) { + out := new(SetAllowRegisterResp) + err := c.cc.Invoke(ctx, "/openim.chat.chat/SetAllowRegister", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *chatClient) GetAllowRegister(ctx context.Context, in *GetAllowRegisterReq, opts ...grpc.CallOption) (*GetAllowRegisterResp, error) { + out := new(GetAllowRegisterResp) + err := c.cc.Invoke(ctx, "/openim.chat.chat/GetAllowRegister", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ChatServer is the server API for Chat service. type ChatServer interface { // Edit personal information - called by the user or an administrator @@ -4190,6 +4457,8 @@ type ChatServer interface { SearchUserInfo(context.Context, *SearchUserInfoReq) (*SearchUserInfoResp, error) // Audio/video call and video meeting GetTokenForVideoMeeting(context.Context, *GetTokenForVideoMeetingReq) (*GetTokenForVideoMeetingResp, error) + SetAllowRegister(context.Context, *SetAllowRegisterReq) (*SetAllowRegisterResp, error) + GetAllowRegister(context.Context, *GetAllowRegisterReq) (*GetAllowRegisterResp, error) } // UnimplementedChatServer can be embedded to have forward compatible implementations. @@ -4256,6 +4525,12 @@ func (*UnimplementedChatServer) SearchUserInfo(context.Context, *SearchUserInfoR func (*UnimplementedChatServer) GetTokenForVideoMeeting(context.Context, *GetTokenForVideoMeetingReq) (*GetTokenForVideoMeetingResp, error) { return nil, status.Errorf(codes.Unimplemented, "method GetTokenForVideoMeeting not implemented") } +func (*UnimplementedChatServer) SetAllowRegister(context.Context, *SetAllowRegisterReq) (*SetAllowRegisterResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetAllowRegister not implemented") +} +func (*UnimplementedChatServer) GetAllowRegister(context.Context, *GetAllowRegisterReq) (*GetAllowRegisterResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAllowRegister not implemented") +} func RegisterChatServer(s *grpc.Server, srv ChatServer) { s.RegisterService(&_Chat_serviceDesc, srv) @@ -4621,6 +4896,42 @@ func _Chat_GetTokenForVideoMeeting_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _Chat_SetAllowRegister_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetAllowRegisterReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChatServer).SetAllowRegister(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/openim.chat.chat/SetAllowRegister", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChatServer).SetAllowRegister(ctx, req.(*SetAllowRegisterReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Chat_GetAllowRegister_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAllowRegisterReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChatServer).GetAllowRegister(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/openim.chat.chat/GetAllowRegister", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChatServer).GetAllowRegister(ctx, req.(*GetAllowRegisterReq)) + } + return interceptor(ctx, in, info, handler) +} + var _Chat_serviceDesc = grpc.ServiceDesc{ ServiceName: "openim.chat.chat", HandlerType: (*ChatServer)(nil), @@ -4705,6 +5016,14 @@ var _Chat_serviceDesc = grpc.ServiceDesc{ MethodName: "GetTokenForVideoMeeting", Handler: _Chat_GetTokenForVideoMeeting_Handler, }, + { + MethodName: "SetAllowRegister", + Handler: _Chat_SetAllowRegister_Handler, + }, + { + MethodName: "GetAllowRegister", + Handler: _Chat_GetAllowRegister_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "chat/chat.proto", diff --git a/pkg/protocol/chat/chat.proto b/pkg/protocol/chat/chat.proto index c66bbd62c..45781533f 100644 --- a/pkg/protocol/chat/chat.proto +++ b/pkg/protocol/chat/chat.proto @@ -274,6 +274,21 @@ message DelUserAccountReq { } message DelUserAccountResp {} +message SetAllowRegisterReq { + bool allowRegister = 1; +} + +message SetAllowRegisterResp { +} + +message GetAllowRegisterReq { +} + +message GetAllowRegisterResp { + bool allowRegister = 1; +} + + service chat { // Edit personal information - called by the user or an administrator rpc UpdateUserInfo(UpdateUserInfoReq) returns (UpdateUserInfoResp); @@ -305,4 +320,7 @@ service chat { // Audio/video call and video meeting rpc GetTokenForVideoMeeting(GetTokenForVideoMeetingReq) returns (GetTokenForVideoMeetingResp); + + rpc SetAllowRegister(SetAllowRegisterReq) returns(SetAllowRegisterResp); + rpc GetAllowRegister(GetAllowRegisterReq) returns(GetAllowRegisterResp); } diff --git a/pkg/protocol/gen.cmd b/pkg/protocol/gen.cmd index ac7ae372e..b837c1d57 100644 --- a/pkg/protocol/gen.cmd +++ b/pkg/protocol/gen.cmd @@ -9,4 +9,9 @@ for %%i in (%PROTO_NAMES%) do ( protoc --go_out=plugins=grpc:./%%i --go_opt=module=github.com/openimsdk/chat/pkg/protocol/%%i %%i/%%i.proto ) +rem Replace "omitempty" in *.pb.go files with UTF-8 encoding +for /r %%f in (*.pb.go) do ( + powershell -Command "(Get-Content -Path '%%f' -Encoding UTF8) -replace ',omitempty\"`"', '\"`"' | Set-Content -Path '%%f' -Encoding UTF8" +) + endlocal diff --git a/pkg/protocol/sdkws/sdkws.proto b/pkg/protocol/sdkws/sdkws.proto index 57301c5be..6a55e7f7f 100644 --- a/pkg/protocol/sdkws/sdkws.proto +++ b/pkg/protocol/sdkws/sdkws.proto @@ -389,7 +389,6 @@ message FriendApplicationRejectedTips { FromToUserID fromToUserID = 1; //from: rejecter; to: requester string handleMsg = 2; } -} // FromUserID Added a friend ToUserID message FriendAddedTips {