添加图片验证

pull/3727/head
hawklin2017 2 months ago
parent bce5747164
commit 34ecfd283d

@ -122,6 +122,17 @@ builds:
- amd64
- arm64
- binary: openim-rpc-captcha
id: openim-rpc-captcha
main: ./cmd/openim-rpc/openim-rpc-captcha/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-rpc-conversation
id: openim-rpc-conversation
main: ./cmd/openim-rpc/openim-rpc-conversation/main.go
@ -355,6 +366,7 @@ nfpms:
- openim-msgtransfer
- openim-push
- openim-rpc-auth
- openim-rpc-captcha
- openim-rpc-conversation
- openim-rpc-friend
- openim-rpc-group

@ -0,0 +1,12 @@
package main
import (
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
"github.com/openimsdk/tools/system/program"
)
func main() {
if err := cmd.NewCaptchaRpcCmd().Exec(); err != nil {
program.ExitWithError(err)
}
}

@ -0,0 +1,12 @@
rpc:
registerIP: ""
listenIP: 0.0.0.0
autoSetPorts: false
ports: [10520]
prometheus:
enable: false
ports: [12520]
verifyPadding: 8
expireSeconds: 120

@ -9,6 +9,7 @@ rpcRegisterName:
auth: auth
conversation: conversation
third: third
captcha: captcha
imAdminUserID: [ imAdmin ]

@ -102,6 +102,7 @@ require (
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-zookeeper/zk v1.0.3 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
@ -171,6 +172,7 @@ require (
github.com/tklauser/go-sysconf v0.3.16 // indirect
github.com/tklauser/numcpus v0.11.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/wenlng/go-captcha/v2 v2.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
@ -191,7 +193,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/image v0.15.0 // indirect
golang.org/x/image v0.16.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect
golang.org/x/sys v0.42.0 // indirect
@ -226,3 +228,5 @@ require (
golang.org/x/crypto v0.32.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
replace github.com/openimsdk/protocol => ./protocol

@ -178,6 +178,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
@ -450,6 +452,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/wenlng/go-captcha/v2 v2.0.5 h1:+1FpVwJZmLCqEHxOt+HvpUArFGo107nRxOeRVHkZhTc=
github.com/wenlng/go-captcha/v2 v2.0.5/go.mod h1:5hac1em3uXoyC5ipZ0xFv9umNM/waQvYAQdr0cx/h34=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
@ -518,6 +522,8 @@ golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjs
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw=
golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=

@ -0,0 +1,49 @@
package api
import (
"github.com/gin-gonic/gin"
pbcaptcha "github.com/openimsdk/protocol/captcha"
"github.com/openimsdk/tools/a2r"
"github.com/openimsdk/tools/apiresp"
"github.com/openimsdk/tools/log"
)
type CaptchaApi struct {
Client pbcaptcha.CaptchaClient
}
func NewCaptchaApi(client pbcaptcha.CaptchaClient) *CaptchaApi {
return &CaptchaApi{Client: client}
}
func (c *CaptchaApi) GenerateCaptcha(ctx *gin.Context) {
req, err := a2r.ParseRequestNotCheck[pbcaptcha.GenerateCaptchaReq](ctx)
if err != nil {
log.ZError(ctx, "captcha generate request parse failed", err)
apiresp.GinError(ctx, err)
return
}
resp, err := c.Client.GenerateCaptcha(ctx, req)
if err != nil {
log.ZError(ctx, "captcha generate rpc failed", err)
apiresp.GinError(ctx, err)
return
}
apiresp.GinSuccess(ctx, resp)
}
func (c *CaptchaApi) VerifyCaptcha(ctx *gin.Context) {
req, err := a2r.ParseRequestNotCheck[pbcaptcha.VerifyCaptchaReq](ctx)
if err != nil {
log.ZError(ctx, "captcha verify request parse failed", err)
apiresp.GinError(ctx, err)
return
}
resp, err := c.Client.VerifyCaptcha(ctx, req)
if err != nil {
log.ZError(ctx, "captcha verify rpc failed", err, "captchaID", req.GetCaptchaID(), "x", req.GetX(), "y", req.GetY())
apiresp.GinError(ctx, err)
return
}
apiresp.GinSuccess(ctx, resp)
}

@ -46,6 +46,7 @@ func Start(ctx context.Context, index int, cfg *Config) error {
// Determine whether zk is passed according to whether it is a clustered deployment
client, err = kdisc.NewDiscoveryRegister(&cfg.Discovery, &cfg.Share, []string{
cfg.Share.RpcRegisterName.MessageGateway,
cfg.Share.RpcRegisterName.Captcha,
})
if err != nil {
return errs.WrapMsg(err, "failed to register discovery service")

@ -7,6 +7,7 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
pbAuth "github.com/openimsdk/protocol/auth"
pbcaptcha "github.com/openimsdk/protocol/captcha"
"github.com/openimsdk/protocol/conversation"
"github.com/openimsdk/protocol/group"
"github.com/openimsdk/protocol/msg"
@ -81,6 +82,10 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
if err != nil {
return nil, err
}
captchaConn, err := client.GetConn(ctx, config.Share.RpcRegisterName.Captcha)
if err != nil {
return nil, err
}
gin.SetMode(gin.ReleaseMode)
r := gin.New()
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
@ -98,6 +103,7 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
r.Use(prommetricsGin(), gin.RecoveryWithWriter(gin.DefaultErrorWriter, mw.GinPanicErr), mw.CorsHandler(), mw.GinParseOperationID(), GinParseToken(rpcli.NewAuthClient(authConn)))
u := NewUserApi(user.NewUserClient(userConn), client, config.Share.RpcRegisterName)
m := NewMessageApi(msg.NewMsgClient(msgConn), rpcli.NewUserClient(userConn), config.Share.IMAdminUserID)
cp := NewCaptchaApi(pbcaptcha.NewCaptchaClient(captchaConn))
userRouterGroup := r.Group("/user")
{
userRouterGroup.POST("/user_register", u.UserRegister)
@ -264,6 +270,12 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
conversationGroup.POST("/get_pinned_conversation_ids", c.GetPinnedConversationIDs)
}
{
captchaGroup := r.Group("/captcha")
captchaGroup.POST("/generate", cp.GenerateCaptcha)
captchaGroup.POST("/verify", cp.VerifyCaptcha)
}
{
statisticsGroup := r.Group("/statistics")
statisticsGroup.POST("/user/register", u.UserRegisterCount)

@ -0,0 +1,158 @@
package captcha
import (
"context"
"errors"
"time"
"github.com/google/uuid"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
pbcaptcha "github.com/openimsdk/protocol/captcha"
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/discovery"
"github.com/openimsdk/tools/log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"google.golang.org/grpc"
"github.com/wenlng/go-captcha/v2/base/option"
"github.com/wenlng/go-captcha/v2/slide"
)
type Config struct {
RpcConfig config.Captcha
MongodbConfig config.Mongo
Share config.Share
Discovery config.Discovery
}
type server struct {
pbcaptcha.UnimplementedCaptchaServer
conf config.Captcha
capt slide.Captcha
collection *mongo.Collection
}
type captchaDoc struct {
CaptchaID string `bson:"captcha_id"`
X int `bson:"x"`
Y int `bson:"y"`
ExpiredAt time.Time `bson:"expired_at"`
CreateTime time.Time `bson:"create_time"`
VerifyTime time.Time `bson:"verify_time,omitempty"`
}
func Start(ctx context.Context, cfg *Config, _ discovery.SvcDiscoveryRegistry, grpcServer *grpc.Server) error {
mongoClient, err := mongoutil.NewMongoDB(ctx, cfg.MongodbConfig.Build())
if err != nil {
log.ZError(ctx, "captcha connect mongodb failed", err)
return err
}
collection := mongoClient.GetDB().Collection("captcha")
_, err = collection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.D{{Key: "captcha_id", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "expired_at", Value: 1}},
Options: options.Index().SetExpireAfterSeconds(0),
},
})
if err != nil {
log.ZError(ctx, "captcha create mongodb indexes failed", err)
return err
}
s := &server{
conf: cfg.RpcConfig,
capt: slide.NewBuilder().Make(),
collection: collection,
}
if s.conf.ExpireSeconds <= 0 {
s.conf.ExpireSeconds = 120
}
if s.conf.VerifyPadding <= 0 {
s.conf.VerifyPadding = 8
}
pbcaptcha.RegisterCaptchaServer(grpcServer, s)
return nil
}
func (s *server) GenerateCaptcha(ctx context.Context, _ *pbcaptcha.GenerateCaptchaReq) (*pbcaptcha.GenerateCaptchaResp, error) {
captData, err := s.capt.Generate()
if err != nil {
log.ZError(ctx, "captcha generate failed", err)
return nil, err
}
block := captData.GetData()
masterImage, err := captData.GetMasterImage().ToBase64DataWithQuality(option.QualityNone)
if err != nil {
log.ZError(ctx, "captcha encode master image failed", err)
return nil, err
}
tileImage, err := captData.GetTileImage().ToBase64Data()
if err != nil {
log.ZError(ctx, "captcha encode tile image failed", err)
return nil, err
}
id := uuid.NewString()
now := time.Now()
expiredAt := now.Add(time.Duration(s.conf.ExpireSeconds) * time.Second)
_, err = s.collection.InsertOne(ctx, captchaDoc{
CaptchaID: id,
X: block.X,
Y: block.Y,
ExpiredAt: expiredAt,
CreateTime: now,
})
if err != nil {
log.ZError(ctx, "captcha insert mongodb failed", err, "captchaID", id)
return nil, err
}
return &pbcaptcha.GenerateCaptchaResp{
CaptchaID: id,
MasterImage: masterImage,
TileImage: tileImage,
ExpireAt: expiredAt.Unix(),
}, nil
}
func (s *server) VerifyCaptcha(ctx context.Context, req *pbcaptcha.VerifyCaptchaReq) (*pbcaptcha.VerifyCaptchaResp, error) {
now := time.Now()
filter := bson.M{
"captcha_id": req.CaptchaID,
"verify_time": bson.M{"$exists": false},
}
update := bson.M{
"$set": bson.M{
"verify_time": now,
},
}
var doc captchaDoc
err := s.collection.FindOneAndUpdate(
ctx,
filter,
update,
options.FindOneAndUpdate().SetReturnDocument(options.Before),
).Decode(&doc)
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
log.ZWarn(ctx, "captcha not found or already verified", err, "captchaID", req.CaptchaID)
return nil, servererrs.ErrRecordNotFound.WrapMsg("captcha not found, expired, or already verified", "captchaID", req.CaptchaID)
}
log.ZError(ctx, "captcha verify query failed", err, "captchaID", req.CaptchaID)
return nil, servererrs.ErrDatabase.WrapMsg("verify captcha query failed", "captchaID", req.CaptchaID)
}
if now.After(doc.ExpiredAt) {
log.ZWarn(ctx, "captcha expired", nil, "captchaID", req.CaptchaID, "expiredAt", doc.ExpiredAt.Unix())
return nil, servererrs.ErrFileUploadedExpired.WrapMsg("captcha expired", "captchaID", req.CaptchaID)
}
success := slide.Validate(int(req.X), int(req.Y), doc.X, doc.Y, s.conf.VerifyPadding)
if !success {
log.ZWarn(ctx, "captcha validate failed", nil, "captchaID", req.CaptchaID, "x", req.X, "y", req.Y)
}
return &pbcaptcha.VerifyCaptchaResp{Success: success}, nil
}

@ -8,6 +8,7 @@ import (
"fmt"
"os"
"github.com/magefile/mage/sh"
"github.com/openimsdk/gomake/mageutil"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/utils/datautil"
@ -37,6 +38,14 @@ func Build() {
if len(bin) != 0 {
bin = bin[1:]
}
mageutil.WithSpinner("Generating protocol artifacts...", func() {
if err := sh.Run("mage", "-d", "protocol", "GenGo"); err != nil {
mageutil.PrintRed("protocol compilation failed: " + err.Error())
os.Exit(1)
}
})
mageutil.WithSpinner("Building binaries...", func() { mageutil.Build(bin, nil, nil) })
}
@ -54,11 +63,28 @@ func BuildWithCustomConfig() {
ToolsDir: &customToolsDir,
}
mageutil.WithSpinner("Generating protocol artifacts...", func() {
if err := sh.Run("mage", "-d", "protocol", "GenGo"); err != nil {
mageutil.PrintRed("protocol compilation failed: " + err.Error())
os.Exit(1)
}
})
mageutil.WithSpinner("Building binaries with custom config...", func() {
mageutil.Build(bin, config, nil)
})
}
// Protocol generates protobuf artifacts under `./protocol`.
func Protocol() {
mageutil.WithSpinner("Generating protocol artifacts...", func() {
if err := sh.Run("mage", "-d", "protocol", "GenGo"); err != nil {
mageutil.PrintRed("protocol compilation failed: " + err.Error())
os.Exit(1)
}
})
}
func Start() {
mageutil.InitForSSC()
err := setMaxOpenFiles()

@ -34,7 +34,9 @@ var (
OpenIMMsgGatewayCfgFileName string
OpenIMMsgTransferCfgFileName string
OpenIMPushCfgFileName string
OpenIMCaptchaCfgFileName string
OpenIMRPCAuthCfgFileName string
OpenIMRPCCaptchaCfgFileName string
OpenIMRPCConversationCfgFileName string
OpenIMRPCFriendCfgFileName string
OpenIMRPCGroupCfgFileName string
@ -62,7 +64,9 @@ func init() {
OpenIMMsgGatewayCfgFileName = "openim-msggateway.yml"
OpenIMMsgTransferCfgFileName = "openim-msgtransfer.yml"
OpenIMPushCfgFileName = "openim-push.yml"
OpenIMCaptchaCfgFileName = "openim-captcha.yml"
OpenIMRPCAuthCfgFileName = "openim-rpc-auth.yml"
OpenIMRPCCaptchaCfgFileName = "openim-rpc-captcha.yml"
OpenIMRPCConversationCfgFileName = "openim-rpc-conversation.yml"
OpenIMRPCFriendCfgFileName = "openim-rpc-friend.yml"
OpenIMRPCGroupCfgFileName = "openim-rpc-group.yml"
@ -77,7 +81,7 @@ func init() {
KafkaConfigFileName, RedisConfigFileName,
MongodbConfigFileName, MinioConfigFileName, LogConfigFileName,
OpenIMAPICfgFileName, OpenIMCronTaskCfgFileName, OpenIMMsgGatewayCfgFileName,
OpenIMMsgTransferCfgFileName, OpenIMPushCfgFileName, OpenIMRPCAuthCfgFileName,
OpenIMMsgTransferCfgFileName, OpenIMPushCfgFileName, OpenIMCaptchaCfgFileName, OpenIMRPCAuthCfgFileName, OpenIMRPCCaptchaCfgFileName,
OpenIMRPCConversationCfgFileName, OpenIMRPCFriendCfgFileName, OpenIMRPCGroupCfgFileName,
OpenIMRPCMsgCfgFileName, OpenIMRPCThirdCfgFileName, OpenIMRPCUserCfgFileName, DiscoveryConfigFilename,
}

@ -0,0 +1,47 @@
package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/rpc/captcha"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
type CaptchaRpcCmd struct {
*RootCmd
ctx context.Context
configMap map[string]any
captchaConfig *captcha.Config
}
func NewCaptchaRpcCmd() *CaptchaRpcCmd {
var captchaConfig captcha.Config
ret := &CaptchaRpcCmd{captchaConfig: &captchaConfig}
ret.configMap = map[string]any{
OpenIMRPCCaptchaCfgFileName: &captchaConfig.RpcConfig,
MongodbConfigFileName: &captchaConfig.MongodbConfig,
ShareFileName: &captchaConfig.Share,
DiscoveryConfigFilename: &captchaConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
return ret
}
func (c *CaptchaRpcCmd) Exec() error {
return c.Execute()
}
func (c *CaptchaRpcCmd) runE() error {
return startrpc.Start(c.ctx, &c.captchaConfig.Discovery, &c.captchaConfig.RpcConfig.Prometheus, c.captchaConfig.RpcConfig.RPC.ListenIP,
c.captchaConfig.RpcConfig.RPC.RegisterIP, c.captchaConfig.RpcConfig.RPC.AutoSetPorts, c.captchaConfig.RpcConfig.RPC.Ports,
c.Index(), c.captchaConfig.Share.RpcRegisterName.Captcha, &c.captchaConfig.Share, c.captchaConfig,
nil,
captcha.Start)
}

@ -249,6 +249,18 @@ type Auth struct {
} `mapstructure:"tokenPolicy"`
}
type Captcha struct {
RPC struct {
RegisterIP string `mapstructure:"registerIP"`
ListenIP string `mapstructure:"listenIP"`
AutoSetPorts bool `mapstructure:"autoSetPorts"`
Ports []int `mapstructure:"ports"`
} `mapstructure:"rpc"`
Prometheus Prometheus `mapstructure:"prometheus"`
VerifyPadding int `mapstructure:"verifyPadding"`
ExpireSeconds int `mapstructure:"expireSeconds"`
}
type Conversation struct {
RPC struct {
RegisterIP string `mapstructure:"registerIP"`
@ -407,6 +419,7 @@ type RpcRegisterName struct {
Auth string `mapstructure:"auth"`
Conversation string `mapstructure:"conversation"`
Third string `mapstructure:"third"`
Captcha string `mapstructure:"captcha"`
}
func (r *RpcRegisterName) GetServiceNames() []string {
@ -420,6 +433,7 @@ func (r *RpcRegisterName) GetServiceNames() []string {
r.Auth,
r.Conversation,
r.Third,
r.Captcha,
}
}
@ -625,6 +639,7 @@ var (
OpenIMMsgTransferCfgFileName = "openim-msgtransfer.yml"
OpenIMPushCfgFileName = "openim-push.yml"
OpenIMRPCAuthCfgFileName = "openim-rpc-auth.yml"
OpenIMRPCCaptchaCfgFileName = "openim-rpc-captcha.yml"
OpenIMRPCConversationCfgFileName = "openim-rpc-conversation.yml"
OpenIMRPCFriendCfgFileName = "openim-rpc-friend.yml"
OpenIMRPCGroupCfgFileName = "openim-rpc-group.yml"
@ -688,6 +703,10 @@ func (a *Auth) GetConfigFileName() string {
return OpenIMRPCAuthCfgFileName
}
func (c *Captcha) GetConfigFileName() string {
return OpenIMRPCCaptchaCfgFileName
}
func (c *Conversation) GetConfigFileName() string {
return OpenIMRPCConversationCfgFileName
}

@ -7,6 +7,7 @@ serviceBinaries:
openim-msgtransfer: 8
openim-rpc-conversation: 1
openim-rpc-auth: 1
openim-rpc-captcha: 1
openim-rpc-group: 1
openim-rpc-friend: 1
openim-rpc-msg: 1

Loading…
Cancel
Save