From 93f062d0b9e855e0a7a53e295d003bc3cf8bb8b2 Mon Sep 17 00:00:00 2001 From: Steven Date: Sun, 10 Sep 2023 18:56:24 +0800 Subject: [PATCH] chore: update user v2 api --- api/v2/common.go | 11 + api/v2/user_service.go | 124 ++++- proto/api/v2/user_service.proto | 47 +- proto/gen/api/v2/README.md | 50 ++- proto/gen/api/v2/user_service.pb.go | 425 +++++++++++++----- proto/gen/api/v2/user_service.pb.gw.go | 143 +++++- proto/gen/api/v2/user_service_grpc.pb.go | 39 +- store/user.go | 12 +- web/src/components/UsageHeatMap.tsx | 2 +- web/src/helpers/api.ts | 11 +- web/src/helpers/datetime.ts | 4 - web/src/pages/MemoDetail.tsx | 1 + web/src/pages/UserProfile.tsx | 1 + web/src/store/module/memo.ts | 7 +- web/src/store/module/tag.ts | 9 +- web/src/store/module/user.ts | 21 +- web/src/store/v1/user.ts | 10 +- .../types/proto/api/v2/user_service_pb.d.ts | 213 ++++++--- web/src/types/proto/api/v2/user_service_pb.js | 59 ++- 19 files changed, 884 insertions(+), 305 deletions(-) diff --git a/api/v2/common.go b/api/v2/common.go index fbe24519..0115f813 100644 --- a/api/v2/common.go +++ b/api/v2/common.go @@ -15,3 +15,14 @@ func convertRowStatusFromStore(rowStatus store.RowStatus) apiv2pb.RowStatus { return apiv2pb.RowStatus_ROW_STATUS_UNSPECIFIED } } + +func convertRowStatusToStore(rowStatus apiv2pb.RowStatus) store.RowStatus { + switch rowStatus { + case apiv2pb.RowStatus_ACTIVE: + return store.Normal + case apiv2pb.RowStatus_ARCHIVED: + return store.Archived + default: + return store.Normal + } +} diff --git a/api/v2/user_service.go b/api/v2/user_service.go index a61a55c2..a8917091 100644 --- a/api/v2/user_service.go +++ b/api/v2/user_service.go @@ -2,11 +2,17 @@ package v2 import ( "context" + "net/http" + "time" + "github.com/labstack/echo/v4" + "github.com/usememos/memos/common/util" apiv2pb "github.com/usememos/memos/proto/gen/api/v2" "github.com/usememos/memos/store" + "golang.org/x/crypto/bcrypt" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" ) type UserService struct { @@ -24,18 +30,24 @@ func NewUserService(store *store.Store) *UserService { func (s *UserService) GetUser(ctx context.Context, request *apiv2pb.GetUserRequest) (*apiv2pb.GetUserResponse, error) { user, err := s.Store.GetUser(ctx, &store.FindUser{ - Username: &request.Name, + Username: &request.Username, }) if err != nil { - return nil, status.Errorf(codes.Internal, "failed to list tags: %v", err) + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) } if user == nil { return nil, status.Errorf(codes.NotFound, "user not found") } userMessage := convertUserFromStore(user) - // Data desensitization. - userMessage.OpenId = "" + userIDPtr := ctx.Value(UserIDContextKey) + if userIDPtr != nil { + userID := userIDPtr.(int32) + if userID != userMessage.Id { + // Data desensitization. + userMessage.OpenId = "" + } + } response := &apiv2pb.GetUserResponse{ User: userMessage, @@ -43,31 +55,105 @@ func (s *UserService) GetUser(ctx context.Context, request *apiv2pb.GetUserReque return response, nil } +func (s *UserService) UpdateUser(ctx context.Context, request *apiv2pb.UpdateUserRequest) (*apiv2pb.UpdateUserResponse, error) { + userID := ctx.Value(UserIDContextKey).(int32) + currentUser, err := s.Store.GetUser(ctx, &store.FindUser{ + ID: &userID, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if currentUser == nil || (currentUser.ID != userID && currentUser.Role != store.RoleAdmin) { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "update mask is empty") + } + + currentTs := time.Now().Unix() + update := &store.UpdateUser{ + ID: userID, + UpdatedTs: ¤tTs, + } + for _, path := range request.UpdateMask.Paths { + if path == "username" { + update.Username = &request.User.Username + } else if path == "nickname" { + update.Nickname = &request.User.Nickname + } else if path == "email" { + update.Email = &request.User.Email + } else if path == "avatar_url" { + update.AvatarURL = &request.User.AvatarUrl + } else if path == "role" { + role := convertUserRoleToStore(request.User.Role) + update.Role = &role + } else if path == "reset_open_id" { + openID := util.GenUUID() + update.OpenID = &openID + } else if path == "password" { + passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost) + if err != nil { + return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to generate password hash").SetInternal(err) + } + passwordHashStr := string(passwordHash) + update.PasswordHash = &passwordHashStr + } else if path == "row_status" { + rowStatus := convertRowStatusToStore(request.User.RowStatus) + update.RowStatus = &rowStatus + } else { + return nil, status.Errorf(codes.InvalidArgument, "invalid update path: %s", path) + } + } + + user, err := s.Store.UpdateUser(ctx, update) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to update user: %v", err) + } + + response := &apiv2pb.UpdateUserResponse{ + User: convertUserFromStore(user), + } + return response, nil +} + func convertUserFromStore(user *store.User) *apiv2pb.User { return &apiv2pb.User{ - Id: int32(user.ID), - RowStatus: convertRowStatusFromStore(user.RowStatus), - CreatedTs: user.CreatedTs, - UpdatedTs: user.UpdatedTs, - Username: user.Username, - Role: convertUserRoleFromStore(user.Role), - Email: user.Email, - Nickname: user.Nickname, - OpenId: user.OpenID, - AvatarUrl: user.AvatarURL, + Id: int32(user.ID), + RowStatus: convertRowStatusFromStore(user.RowStatus), + CreateTime: timestamppb.New(time.Unix(user.CreatedTs, 0)), + UpdateTime: timestamppb.New(time.Unix(user.UpdatedTs, 0)), + Username: user.Username, + Role: convertUserRoleFromStore(user.Role), + Email: user.Email, + Nickname: user.Nickname, + OpenId: user.OpenID, + AvatarUrl: user.AvatarURL, } } -func convertUserRoleFromStore(role store.Role) apiv2pb.Role { +func convertUserRoleFromStore(role store.Role) apiv2pb.User_Role { switch role { case store.RoleHost: - return apiv2pb.Role_HOST + return apiv2pb.User_HOST case store.RoleAdmin: - return apiv2pb.Role_ADMIN + return apiv2pb.User_ADMIN case store.RoleUser: - return apiv2pb.Role_USER + return apiv2pb.User_USER default: - return apiv2pb.Role_ROLE_UNSPECIFIED + return apiv2pb.User_ROLE_UNSPECIFIED + } +} + +func convertUserRoleToStore(role apiv2pb.User_Role) store.Role { + switch role { + case apiv2pb.User_HOST: + return store.RoleHost + case apiv2pb.User_ADMIN: + return store.RoleAdmin + case apiv2pb.User_USER: + return store.RoleUser + default: + return store.RoleUser } } diff --git a/proto/api/v2/user_service.proto b/proto/api/v2/user_service.proto index b54846ca..0f218703 100644 --- a/proto/api/v2/user_service.proto +++ b/proto/api/v2/user_service.proto @@ -6,13 +6,20 @@ import "api/v2/common.proto"; import "api/v2/memo_service.proto"; import "google/api/annotations.proto"; import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; option go_package = "gen/api/v2"; service UserService { rpc GetUser(GetUserRequest) returns (GetUserResponse) { - option (google.api.http) = {get: "/api/v2/users/{name}"}; - option (google.api.method_signature) = "name"; + option (google.api.http) = {get: "/api/v2/users/{username}"}; + option (google.api.method_signature) = "username"; + } + rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse) { + option (google.api.http) = {patch: "/api/v2/users/{username}"}; + option (google.api.method_signature) = "username"; } } @@ -21,12 +28,19 @@ message User { RowStatus row_status = 2; - int64 created_ts = 3; + google.protobuf.Timestamp create_time = 3; - int64 updated_ts = 4; + google.protobuf.Timestamp update_time = 4; string username = 5; + enum Role { + ROLE_UNSPECIFIED = 0; + HOST = 1; + ADMIN = 2; + USER = 3; + } + Role role = 6; string email = 7; @@ -36,26 +50,31 @@ message User { string open_id = 9; string avatar_url = 10; -} -enum Role { - ROLE_UNSPECIFIED = 0; - - HOST = 1; - - ADMIN = 2; - - USER = 3; + string password = 11 [(google.api.field_behavior) = INPUT_ONLY]; } message GetUserRequest { - string name = 1; + string username = 1; } message GetUserResponse { User user = 1; } +message UpdateUserRequest { + string username = 1; + + User user = 2; + + // The update mask applies to the user resource. + google.protobuf.FieldMask update_mask = 3; +} + +message UpdateUserResponse { + User user = 1; +} + message UserSetting { // The user id of the setting. int32 user_id = 1; diff --git a/proto/gen/api/v2/README.md b/proto/gen/api/v2/README.md index 984f78a2..96ea4dfe 100644 --- a/proto/gen/api/v2/README.md +++ b/proto/gen/api/v2/README.md @@ -36,11 +36,13 @@ - [api/v2/user_service.proto](#api_v2_user_service-proto) - [GetUserRequest](#memos-api-v2-GetUserRequest) - [GetUserResponse](#memos-api-v2-GetUserResponse) + - [UpdateUserRequest](#memos-api-v2-UpdateUserRequest) + - [UpdateUserResponse](#memos-api-v2-UpdateUserResponse) - [User](#memos-api-v2-User) - [UserSetting](#memos-api-v2-UserSetting) - [UserSettingValue](#memos-api-v2-UserSettingValue) - - [Role](#memos-api-v2-Role) + - [User.Role](#memos-api-v2-User-Role) - [UserSetting.Key](#memos-api-v2-UserSetting-Key) - [UserService](#memos-api-v2-UserService) @@ -395,7 +397,7 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | +| username | [string](#string) | | | @@ -417,6 +419,38 @@ + + +### UpdateUserRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| username | [string](#string) | | | +| user | [User](#memos-api-v2-User) | | | +| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | The update mask applies to the user resource. | + + + + + + + + +### UpdateUserResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| user | [User](#memos-api-v2-User) | | | + + + + + + ### User @@ -427,14 +461,15 @@ | ----- | ---- | ----- | ----------- | | id | [int32](#int32) | | | | row_status | [RowStatus](#memos-api-v2-RowStatus) | | | -| created_ts | [int64](#int64) | | | -| updated_ts | [int64](#int64) | | | +| create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| update_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | | username | [string](#string) | | | -| role | [Role](#memos-api-v2-Role) | | | +| role | [User.Role](#memos-api-v2-User-Role) | | | | email | [string](#string) | | | | nickname | [string](#string) | | | | open_id | [string](#string) | | | | avatar_url | [string](#string) | | | +| password | [string](#string) | | | @@ -476,9 +511,9 @@ - + -### Role +### User.Role | Name | Number | Description | @@ -517,6 +552,7 @@ | Method Name | Request Type | Response Type | Description | | ----------- | ------------ | ------------- | ------------| | GetUser | [GetUserRequest](#memos-api-v2-GetUserRequest) | [GetUserResponse](#memos-api-v2-GetUserResponse) | | +| UpdateUser | [UpdateUserRequest](#memos-api-v2-UpdateUserRequest) | [UpdateUserResponse](#memos-api-v2-UpdateUserResponse) | | diff --git a/proto/gen/api/v2/user_service.pb.go b/proto/gen/api/v2/user_service.pb.go index a03a1dee..6e75bcf3 100644 --- a/proto/gen/api/v2/user_service.pb.go +++ b/proto/gen/api/v2/user_service.pb.go @@ -10,6 +10,8 @@ import ( _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -21,24 +23,24 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type Role int32 +type User_Role int32 const ( - Role_ROLE_UNSPECIFIED Role = 0 - Role_HOST Role = 1 - Role_ADMIN Role = 2 - Role_USER Role = 3 + User_ROLE_UNSPECIFIED User_Role = 0 + User_HOST User_Role = 1 + User_ADMIN User_Role = 2 + User_USER User_Role = 3 ) -// Enum value maps for Role. +// Enum value maps for User_Role. var ( - Role_name = map[int32]string{ + User_Role_name = map[int32]string{ 0: "ROLE_UNSPECIFIED", 1: "HOST", 2: "ADMIN", 3: "USER", } - Role_value = map[string]int32{ + User_Role_value = map[string]int32{ "ROLE_UNSPECIFIED": 0, "HOST": 1, "ADMIN": 2, @@ -46,31 +48,31 @@ var ( } ) -func (x Role) Enum() *Role { - p := new(Role) +func (x User_Role) Enum() *User_Role { + p := new(User_Role) *p = x return p } -func (x Role) String() string { +func (x User_Role) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (Role) Descriptor() protoreflect.EnumDescriptor { +func (User_Role) Descriptor() protoreflect.EnumDescriptor { return file_api_v2_user_service_proto_enumTypes[0].Descriptor() } -func (Role) Type() protoreflect.EnumType { +func (User_Role) Type() protoreflect.EnumType { return &file_api_v2_user_service_proto_enumTypes[0] } -func (x Role) Number() protoreflect.EnumNumber { +func (x User_Role) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } -// Deprecated: Use Role.Descriptor instead. -func (Role) EnumDescriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{0} +// Deprecated: Use User_Role.Descriptor instead. +func (User_Role) EnumDescriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{0, 0} } type UserSetting_Key int32 @@ -129,7 +131,7 @@ func (x UserSetting_Key) Number() protoreflect.EnumNumber { // Deprecated: Use UserSetting_Key.Descriptor instead. func (UserSetting_Key) EnumDescriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{3, 0} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{5, 0} } type User struct { @@ -137,16 +139,17 @@ type User struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - RowStatus RowStatus `protobuf:"varint,2,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"` - CreatedTs int64 `protobuf:"varint,3,opt,name=created_ts,json=createdTs,proto3" json:"created_ts,omitempty"` - UpdatedTs int64 `protobuf:"varint,4,opt,name=updated_ts,json=updatedTs,proto3" json:"updated_ts,omitempty"` - Username string `protobuf:"bytes,5,opt,name=username,proto3" json:"username,omitempty"` - Role Role `protobuf:"varint,6,opt,name=role,proto3,enum=memos.api.v2.Role" json:"role,omitempty"` - Email string `protobuf:"bytes,7,opt,name=email,proto3" json:"email,omitempty"` - Nickname string `protobuf:"bytes,8,opt,name=nickname,proto3" json:"nickname,omitempty"` - OpenId string `protobuf:"bytes,9,opt,name=open_id,json=openId,proto3" json:"open_id,omitempty"` - AvatarUrl string `protobuf:"bytes,10,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"` + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + RowStatus RowStatus `protobuf:"varint,2,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"` + CreateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` + UpdateTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` + Username string `protobuf:"bytes,5,opt,name=username,proto3" json:"username,omitempty"` + Role User_Role `protobuf:"varint,6,opt,name=role,proto3,enum=memos.api.v2.User_Role" json:"role,omitempty"` + Email string `protobuf:"bytes,7,opt,name=email,proto3" json:"email,omitempty"` + Nickname string `protobuf:"bytes,8,opt,name=nickname,proto3" json:"nickname,omitempty"` + OpenId string `protobuf:"bytes,9,opt,name=open_id,json=openId,proto3" json:"open_id,omitempty"` + AvatarUrl string `protobuf:"bytes,10,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"` + Password string `protobuf:"bytes,11,opt,name=password,proto3" json:"password,omitempty"` } func (x *User) Reset() { @@ -195,18 +198,18 @@ func (x *User) GetRowStatus() RowStatus { return RowStatus_ROW_STATUS_UNSPECIFIED } -func (x *User) GetCreatedTs() int64 { +func (x *User) GetCreateTime() *timestamppb.Timestamp { if x != nil { - return x.CreatedTs + return x.CreateTime } - return 0 + return nil } -func (x *User) GetUpdatedTs() int64 { +func (x *User) GetUpdateTime() *timestamppb.Timestamp { if x != nil { - return x.UpdatedTs + return x.UpdateTime } - return 0 + return nil } func (x *User) GetUsername() string { @@ -216,11 +219,11 @@ func (x *User) GetUsername() string { return "" } -func (x *User) GetRole() Role { +func (x *User) GetRole() User_Role { if x != nil { return x.Role } - return Role_ROLE_UNSPECIFIED + return User_ROLE_UNSPECIFIED } func (x *User) GetEmail() string { @@ -251,12 +254,19 @@ func (x *User) GetAvatarUrl() string { return "" } +func (x *User) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + type GetUserRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` } func (x *GetUserRequest) Reset() { @@ -291,9 +301,9 @@ func (*GetUserRequest) Descriptor() ([]byte, []int) { return file_api_v2_user_service_proto_rawDescGZIP(), []int{1} } -func (x *GetUserRequest) GetName() string { +func (x *GetUserRequest) GetUsername() string { if x != nil { - return x.Name + return x.Username } return "" } @@ -345,6 +355,117 @@ func (x *GetUserResponse) GetUser() *User { return nil } +type UpdateUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + User *User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` + // The update mask applies to the user resource. + UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,3,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` +} + +func (x *UpdateUserRequest) Reset() { + *x = UpdateUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserRequest) ProtoMessage() {} + +func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[3] + 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 UpdateUserRequest.ProtoReflect.Descriptor instead. +func (*UpdateUserRequest) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateUserRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *UpdateUserRequest) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +func (x *UpdateUserRequest) GetUpdateMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +type UpdateUserResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *UpdateUserResponse) Reset() { + *x = UpdateUserResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserResponse) ProtoMessage() {} + +func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[4] + 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 UpdateUserResponse.ProtoReflect.Descriptor instead. +func (*UpdateUserResponse) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateUserResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + type UserSetting struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -361,7 +482,7 @@ type UserSetting struct { func (x *UserSetting) Reset() { *x = UserSetting{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[3] + mi := &file_api_v2_user_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -374,7 +495,7 @@ func (x *UserSetting) String() string { func (*UserSetting) ProtoMessage() {} func (x *UserSetting) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[3] + mi := &file_api_v2_user_service_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -387,7 +508,7 @@ func (x *UserSetting) ProtoReflect() protoreflect.Message { // Deprecated: Use UserSetting.ProtoReflect.Descriptor instead. func (*UserSetting) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{3} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{5} } func (x *UserSetting) GetUserId() int32 { @@ -426,7 +547,7 @@ type UserSettingValue struct { func (x *UserSettingValue) Reset() { *x = UserSettingValue{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[4] + mi := &file_api_v2_user_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -439,7 +560,7 @@ func (x *UserSettingValue) String() string { func (*UserSettingValue) ProtoMessage() {} func (x *UserSettingValue) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[4] + mi := &file_api_v2_user_service_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -452,7 +573,7 @@ func (x *UserSettingValue) ProtoReflect() protoreflect.Message { // Deprecated: Use UserSettingValue.ProtoReflect.Descriptor instead. func (*UserSettingValue) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{4} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{6} } func (m *UserSettingValue) GetValue() isUserSettingValue_Value { @@ -505,29 +626,59 @@ var file_api_v2_user_service_proto_rawDesc = []byte{ 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xba, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x6f, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54, 0x73, - 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x73, 0x12, + 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x03, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, + 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x72, - 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, - 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, - 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, - 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x22, 0x24, 0x0a, - 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x72, + 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x6f, + 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, + 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x70, + 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x70, 0x65, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, + 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x04, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x22, 0x3b, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, + 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, + 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x03, + 0x22, 0x2c, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x39, + 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x94, 0x01, 0x0a, 0x11, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, + 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, + 0x22, 0x3c, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0xf0, @@ -554,30 +705,35 @@ var file_api_v2_user_service_proto_rawDesc = []byte{ 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x0f, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x3b, 0x0a, 0x04, 0x52, - 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x53, - 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x08, - 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x03, 0x32, 0x7a, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6b, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, - 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, - 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x23, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x6e, - 0x61, 0x6d, 0x65, 0x7d, 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, - 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, - 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, - 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, - 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x80, 0x02, 0x0a, 0x0b, + 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2b, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, + 0x12, 0x7c, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1f, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x2b, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1a, 0x32, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, + 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x42, 0xa8, + 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, + 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, + 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, + 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -593,32 +749,43 @@ func file_api_v2_user_service_proto_rawDescGZIP() []byte { } var file_api_v2_user_service_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_api_v2_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_api_v2_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_api_v2_user_service_proto_goTypes = []interface{}{ - (Role)(0), // 0: memos.api.v2.Role - (UserSetting_Key)(0), // 1: memos.api.v2.UserSetting.Key - (*User)(nil), // 2: memos.api.v2.User - (*GetUserRequest)(nil), // 3: memos.api.v2.GetUserRequest - (*GetUserResponse)(nil), // 4: memos.api.v2.GetUserResponse - (*UserSetting)(nil), // 5: memos.api.v2.UserSetting - (*UserSettingValue)(nil), // 6: memos.api.v2.UserSettingValue - (RowStatus)(0), // 7: memos.api.v2.RowStatus - (Visibility)(0), // 8: memos.api.v2.Visibility + (User_Role)(0), // 0: memos.api.v2.User.Role + (UserSetting_Key)(0), // 1: memos.api.v2.UserSetting.Key + (*User)(nil), // 2: memos.api.v2.User + (*GetUserRequest)(nil), // 3: memos.api.v2.GetUserRequest + (*GetUserResponse)(nil), // 4: memos.api.v2.GetUserResponse + (*UpdateUserRequest)(nil), // 5: memos.api.v2.UpdateUserRequest + (*UpdateUserResponse)(nil), // 6: memos.api.v2.UpdateUserResponse + (*UserSetting)(nil), // 7: memos.api.v2.UserSetting + (*UserSettingValue)(nil), // 8: memos.api.v2.UserSettingValue + (RowStatus)(0), // 9: memos.api.v2.RowStatus + (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp + (*fieldmaskpb.FieldMask)(nil), // 11: google.protobuf.FieldMask + (Visibility)(0), // 12: memos.api.v2.Visibility } var file_api_v2_user_service_proto_depIdxs = []int32{ - 7, // 0: memos.api.v2.User.row_status:type_name -> memos.api.v2.RowStatus - 0, // 1: memos.api.v2.User.role:type_name -> memos.api.v2.Role - 2, // 2: memos.api.v2.GetUserResponse.user:type_name -> memos.api.v2.User - 1, // 3: memos.api.v2.UserSetting.key:type_name -> memos.api.v2.UserSetting.Key - 6, // 4: memos.api.v2.UserSetting.value:type_name -> memos.api.v2.UserSettingValue - 8, // 5: memos.api.v2.UserSettingValue.visibility_value:type_name -> memos.api.v2.Visibility - 3, // 6: memos.api.v2.UserService.GetUser:input_type -> memos.api.v2.GetUserRequest - 4, // 7: memos.api.v2.UserService.GetUser:output_type -> memos.api.v2.GetUserResponse - 7, // [7:8] is the sub-list for method output_type - 6, // [6:7] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 9, // 0: memos.api.v2.User.row_status:type_name -> memos.api.v2.RowStatus + 10, // 1: memos.api.v2.User.create_time:type_name -> google.protobuf.Timestamp + 10, // 2: memos.api.v2.User.update_time:type_name -> google.protobuf.Timestamp + 0, // 3: memos.api.v2.User.role:type_name -> memos.api.v2.User.Role + 2, // 4: memos.api.v2.GetUserResponse.user:type_name -> memos.api.v2.User + 2, // 5: memos.api.v2.UpdateUserRequest.user:type_name -> memos.api.v2.User + 11, // 6: memos.api.v2.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask + 2, // 7: memos.api.v2.UpdateUserResponse.user:type_name -> memos.api.v2.User + 1, // 8: memos.api.v2.UserSetting.key:type_name -> memos.api.v2.UserSetting.Key + 8, // 9: memos.api.v2.UserSetting.value:type_name -> memos.api.v2.UserSettingValue + 12, // 10: memos.api.v2.UserSettingValue.visibility_value:type_name -> memos.api.v2.Visibility + 3, // 11: memos.api.v2.UserService.GetUser:input_type -> memos.api.v2.GetUserRequest + 5, // 12: memos.api.v2.UserService.UpdateUser:input_type -> memos.api.v2.UpdateUserRequest + 4, // 13: memos.api.v2.UserService.GetUser:output_type -> memos.api.v2.GetUserResponse + 6, // 14: memos.api.v2.UserService.UpdateUser:output_type -> memos.api.v2.UpdateUserResponse + 13, // [13:15] is the sub-list for method output_type + 11, // [11:13] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_api_v2_user_service_proto_init() } @@ -666,7 +833,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserSetting); i { + switch v := v.(*UpdateUserRequest); i { case 0: return &v.state case 1: @@ -678,6 +845,30 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserSetting); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserSettingValue); i { case 0: return &v.state @@ -690,7 +881,7 @@ func file_api_v2_user_service_proto_init() { } } } - file_api_v2_user_service_proto_msgTypes[4].OneofWrappers = []interface{}{ + file_api_v2_user_service_proto_msgTypes[6].OneofWrappers = []interface{}{ (*UserSettingValue_StringValue)(nil), (*UserSettingValue_VisibilityValue)(nil), } @@ -700,7 +891,7 @@ func file_api_v2_user_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_user_service_proto_rawDesc, NumEnums: 2, - NumMessages: 5, + NumMessages: 7, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/api/v2/user_service.pb.gw.go b/proto/gen/api/v2/user_service.pb.gw.go index a71ef0d6..1fcba480 100644 --- a/proto/gen/api/v2/user_service.pb.gw.go +++ b/proto/gen/api/v2/user_service.pb.gw.go @@ -42,14 +42,14 @@ func request_UserService_GetUser_0(ctx context.Context, marshaler runtime.Marsha _ = err ) - val, ok = pathParams["name"] + val, ok = pathParams["username"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } - protoReq.Name, err = runtime.String(val) + protoReq.Username, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } msg, err := client.GetUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -68,14 +68,14 @@ func local_request_UserService_GetUser_0(ctx context.Context, marshaler runtime. _ = err ) - val, ok = pathParams["name"] + val, ok = pathParams["username"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } - protoReq.Name, err = runtime.String(val) + protoReq.Username, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } msg, err := server.GetUser(ctx, &protoReq) @@ -83,6 +83,76 @@ func local_request_UserService_GetUser_0(ctx context.Context, marshaler runtime. } +var ( + filter_UserService_UpdateUser_0 = &utilities.DoubleArray{Encoding: map[string]int{"username": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} +) + +func request_UserService_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateUserRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["username"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + } + + protoReq.Username, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_UpdateUser_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpdateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_UserService_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateUserRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["username"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + } + + protoReq.Username, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_UpdateUser_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpdateUser(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterUserServiceHandlerServer registers the http handlers for service UserService to "mux". // UnaryRPC :call UserServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -97,7 +167,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/GetUser", runtime.WithHTTPPathPattern("/api/v2/users/{name}")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/GetUser", runtime.WithHTTPPathPattern("/api/v2/users/{username}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -114,6 +184,31 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("PATCH", pattern_UserService_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v2/users/{username}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_UserService_UpdateUser_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -161,7 +256,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/GetUser", runtime.WithHTTPPathPattern("/api/v2/users/{name}")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/GetUser", runtime.WithHTTPPathPattern("/api/v2/users/{username}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -177,13 +272,39 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("PATCH", pattern_UserService_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v2/users/{username}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_UserService_UpdateUser_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } var ( - pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "users", "name"}, "")) + pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "users", "username"}, "")) + + pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "users", "username"}, "")) ) var ( forward_UserService_GetUser_0 = runtime.ForwardResponseMessage + + forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage ) diff --git a/proto/gen/api/v2/user_service_grpc.pb.go b/proto/gen/api/v2/user_service_grpc.pb.go index 18600fea..f6f9f2ce 100644 --- a/proto/gen/api/v2/user_service_grpc.pb.go +++ b/proto/gen/api/v2/user_service_grpc.pb.go @@ -19,7 +19,8 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - UserService_GetUser_FullMethodName = "/memos.api.v2.UserService/GetUser" + UserService_GetUser_FullMethodName = "/memos.api.v2.UserService/GetUser" + UserService_UpdateUser_FullMethodName = "/memos.api.v2.UserService/UpdateUser" ) // UserServiceClient is the client API for UserService service. @@ -27,6 +28,7 @@ const ( // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type UserServiceClient interface { GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) + UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) } type userServiceClient struct { @@ -46,11 +48,21 @@ func (c *userServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opt return out, nil } +func (c *userServiceClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) { + out := new(UpdateUserResponse) + err := c.cc.Invoke(ctx, UserService_UpdateUser_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // UserServiceServer is the server API for UserService service. // All implementations must embed UnimplementedUserServiceServer // for forward compatibility type UserServiceServer interface { GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) + UpdateUser(context.Context, *UpdateUserRequest) (*UpdateUserResponse, error) mustEmbedUnimplementedUserServiceServer() } @@ -61,6 +73,9 @@ type UnimplementedUserServiceServer struct { func (UnimplementedUserServiceServer) GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented") } +func (UnimplementedUserServiceServer) UpdateUser(context.Context, *UpdateUserRequest) (*UpdateUserResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateUser not implemented") +} func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} // UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. @@ -92,6 +107,24 @@ func _UserService_GetUser_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).UpdateUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_UpdateUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).UpdateUser(ctx, req.(*UpdateUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + // UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -103,6 +136,10 @@ var UserService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetUser", Handler: _UserService_GetUser_Handler, }, + { + MethodName: "UpdateUser", + Handler: _UserService_UpdateUser_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api/v2/user_service.proto", diff --git a/store/user.go b/store/user.go index 3c10795b..e5939300 100644 --- a/store/user.go +++ b/store/user.go @@ -52,12 +52,12 @@ type UpdateUser struct { UpdatedTs *int64 RowStatus *RowStatus - Username *string `json:"username"` - Email *string `json:"email"` - Nickname *string `json:"nickname"` - Password *string `json:"password"` - ResetOpenID *bool `json:"resetOpenId"` - AvatarURL *string `json:"avatarUrl"` + Username *string + Role *Role + Email *string + Nickname *string + Password *string + AvatarURL *string PasswordHash *string OpenID *string } diff --git a/web/src/components/UsageHeatMap.tsx b/web/src/components/UsageHeatMap.tsx index e83270b4..9f543cb2 100644 --- a/web/src/components/UsageHeatMap.tsx +++ b/web/src/components/UsageHeatMap.tsx @@ -53,7 +53,7 @@ const UsageHeatMap = () => { if (!user) { return; } - setCreatedDays(Math.ceil((Date.now() - getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24)); + setCreatedDays(Math.ceil((Date.now() - getTimeStampByDate(user.createTime)) / 1000 / 3600 / 24)); }); }, [currentUsername]); diff --git a/web/src/helpers/api.ts b/web/src/helpers/api.ts index 9c8ed6cd..d3bc20ec 100644 --- a/web/src/helpers/api.ts +++ b/web/src/helpers/api.ts @@ -1,4 +1,5 @@ import axios from "axios"; +import { GetUserResponse } from "@/types/proto/api/v2/user_service_pb"; export function getSystemStatus() { return axios.get("/api/v1/status"); @@ -55,7 +56,7 @@ export function getUserList() { } export function getUserByUsername(username: string) { - return axios.get(`/api/v1/user/name/${username}`); + return axios.get(`/api/v2/users/${username}`); } export function upsertUserSetting(upsert: UserSettingUpsert) { @@ -183,12 +184,8 @@ export function deleteMemoResource(memoId: MemoId, resourceId: ResourceId) { return axios.delete(`/api/v1/memo/${memoId}/resource/${resourceId}`); } -export function getTagList(tagFind?: TagFind) { - const queryList = []; - if (tagFind?.creatorUsername) { - queryList.push(`creatorUsername=${tagFind.creatorUsername}`); - } - return axios.get(`/api/v1/tag?${queryList.join("&")}`); +export function getTagList() { + return axios.get(`/api/v1/tag`); } export function getTagSuggestionList() { diff --git a/web/src/helpers/datetime.ts b/web/src/helpers/datetime.ts index 8b06a2aa..84900f1f 100644 --- a/web/src/helpers/datetime.ts +++ b/web/src/helpers/datetime.ts @@ -6,10 +6,6 @@ export function convertToMillis(localSetting: LocalSetting) { } export function getTimeStampByDate(t: Date | number | string): number { - if (typeof t === "string") { - t = t.replaceAll("-", "/"); - } - return new Date(t).getTime(); } diff --git a/web/src/pages/MemoDetail.tsx b/web/src/pages/MemoDetail.tsx index 48c442f4..f775d28c 100644 --- a/web/src/pages/MemoDetail.tsx +++ b/web/src/pages/MemoDetail.tsx @@ -7,6 +7,7 @@ import UserAvatar from "@/components/UserAvatar"; import useLoading from "@/hooks/useLoading"; import { useMemoStore } from "@/store/module"; import { useUserV1Store } from "@/store/v1"; +import { User } from "@/types/proto/api/v2/user_service_pb"; const MemoDetail = () => { const params = useParams(); diff --git a/web/src/pages/UserProfile.tsx b/web/src/pages/UserProfile.tsx index 5d18dc48..a938b333 100644 --- a/web/src/pages/UserProfile.tsx +++ b/web/src/pages/UserProfile.tsx @@ -7,6 +7,7 @@ import UserAvatar from "@/components/UserAvatar"; import useLoading from "@/hooks/useLoading"; import { useUserStore } from "@/store/module"; import { useUserV1Store } from "@/store/v1"; +import { User } from "@/types/proto/api/v2/user_service_pb"; import { useTranslate } from "@/utils/i18n"; const UserProfile = () => { diff --git a/web/src/store/module/memo.ts b/web/src/store/module/memo.ts index e94280ba..2cd6da77 100644 --- a/web/src/store/module/memo.ts +++ b/web/src/store/module/memo.ts @@ -4,7 +4,7 @@ import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts"; import store, { useAppSelector } from "../"; import { createMemo, deleteMemo, patchMemo, upsertMemos } from "../reducer/memo"; import { useMemoCacheStore } from "../v1"; -import { useUserStore } from "./"; +import { getUsernameFromPath, useUserStore } from "./"; export const convertResponseModelMemo = (memo: Memo): Memo => { return { @@ -40,7 +40,7 @@ export const useMemoStore = () => { offset, }; if (userStore.isVisitorMode()) { - memoFind.creatorUsername = userStore.getUsernameFromPath(); + memoFind.creatorUsername = getUsernameFromPath(); } const { data } = await api.getMemoList(memoFind); const fetchedMemos = data.map((m) => convertResponseModelMemo(m)); @@ -70,9 +70,6 @@ export const useMemoStore = () => { const memoFind: MemoFind = { rowStatus: "ARCHIVED", }; - if (userStore.isVisitorMode()) { - memoFind.creatorUsername = userStore.getUsernameFromPath(); - } const { data } = await api.getMemoList(memoFind); const archivedMemos = data.map((m) => { return convertResponseModelMemo(m); diff --git a/web/src/store/module/tag.ts b/web/src/store/module/tag.ts index 737b3f81..efad18dc 100644 --- a/web/src/store/module/tag.ts +++ b/web/src/store/module/tag.ts @@ -1,22 +1,17 @@ import * as api from "@/helpers/api"; import store, { useAppSelector } from ".."; import { deleteTag, setTags, upsertTag } from "../reducer/tag"; -import { useUserStore } from "./"; export const useTagStore = () => { const state = useAppSelector((state) => state.tag); - const userStore = useUserStore(); + return { state, getState: () => { return store.getState().tag; }, fetchTags: async () => { - const tagFind: TagFind = {}; - if (userStore.isVisitorMode()) { - tagFind.creatorUsername = userStore.getUsernameFromPath(); - } - const { data } = await api.getTagList(tagFind); + const { data } = await api.getTagList(); store.dispatch(setTags(data)); }, upsertTag: async (tagName: string) => { diff --git a/web/src/store/module/user.ts b/web/src/store/module/user.ts index 022fdade..5662cbdb 100644 --- a/web/src/store/module/user.ts +++ b/web/src/store/module/user.ts @@ -71,16 +71,6 @@ export const initialUserState = async () => { } }; -const getUsernameFromPath = () => { - const pathname = window.location.pathname; - const usernameRegex = /^\/u\/(\w+).*/; - const result = pathname.match(usernameRegex); - if (result && result.length === 2) { - return String(result[1]); - } - return undefined; -}; - const doSignIn = async () => { const { data: user } = await api.getMyselfUser(); if (user) { @@ -95,6 +85,16 @@ const doSignOut = async () => { await api.signout(); }; +export const getUsernameFromPath = () => { + const pathname = window.location.pathname; + const usernameRegex = /^\/u\/(\w+).*/; + const result = pathname.match(usernameRegex); + if (result && result.length === 2) { + return String(result[1]); + } + return undefined; +}; + export const useUserStore = () => { const state = useAppSelector((state) => state.user); @@ -108,7 +108,6 @@ export const useUserStore = () => { return store.getState().user; }, isVisitorMode, - getUsernameFromPath, doSignIn, doSignOut, getCurrentUsername: () => { diff --git a/web/src/store/v1/user.ts b/web/src/store/v1/user.ts index 9d72670e..d7c80b95 100644 --- a/web/src/store/v1/user.ts +++ b/web/src/store/v1/user.ts @@ -1,6 +1,6 @@ import { create } from "zustand"; import * as api from "@/helpers/api"; -import { convertResponseModelUser } from "../module"; +import { User } from "@/types/proto/api/v2/user_service_pb"; interface UserV1Store { userMapByUsername: Record; @@ -24,9 +24,13 @@ const useUserV1Store = create()((set, get) => ({ const promise = api.getUserByUsername(username); requestCache.set(username, promise); - const { data } = await promise; + const { + data: { user: user }, + } = await promise; + if (!user) { + throw new Error("User not found"); + } requestCache.delete(username); - const user = convertResponseModelUser(data); userMap[username] = user; set(userMap); return user; diff --git a/web/src/types/proto/api/v2/user_service_pb.d.ts b/web/src/types/proto/api/v2/user_service_pb.d.ts index 7f01c0c5..77721c90 100644 --- a/web/src/types/proto/api/v2/user_service_pb.d.ts +++ b/web/src/types/proto/api/v2/user_service_pb.d.ts @@ -3,15 +3,89 @@ /* eslint-disable */ // @ts-nocheck -import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; +import type { BinaryReadOptions, FieldList, FieldMask, JsonReadOptions, JsonValue, PartialMessage, PlainMessage, Timestamp } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; import type { RowStatus } from "./common_pb.js"; import type { Visibility } from "./memo_service_pb.js"; /** - * @generated from enum memos.api.v2.Role + * @generated from message memos.api.v2.User */ -export declare enum Role { +export declare class User extends Message { + /** + * @generated from field: int32 id = 1; + */ + id: number; + + /** + * @generated from field: memos.api.v2.RowStatus row_status = 2; + */ + rowStatus: RowStatus; + + /** + * @generated from field: google.protobuf.Timestamp create_time = 3; + */ + createTime?: Timestamp; + + /** + * @generated from field: google.protobuf.Timestamp update_time = 4; + */ + updateTime?: Timestamp; + + /** + * @generated from field: string username = 5; + */ + username: string; + + /** + * @generated from field: memos.api.v2.User.Role role = 6; + */ + role: User_Role; + + /** + * @generated from field: string email = 7; + */ + email: string; + + /** + * @generated from field: string nickname = 8; + */ + nickname: string; + + /** + * @generated from field: string open_id = 9; + */ + openId: string; + + /** + * @generated from field: string avatar_url = 10; + */ + avatarUrl: string; + + /** + * @generated from field: string password = 11; + */ + password: string; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "memos.api.v2.User"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): User; + + static fromJson(jsonValue: JsonValue, options?: Partial): User; + + static fromJsonString(jsonString: string, options?: Partial): User; + + static equals(a: User | PlainMessage | undefined, b: User | PlainMessage | undefined): boolean; +} + +/** + * @generated from enum memos.api.v2.User.Role + */ +export declare enum User_Role { /** * @generated from enum value: ROLE_UNSPECIFIED = 0; */ @@ -33,83 +107,14 @@ export declare enum Role { USER = 3, } -/** - * @generated from message memos.api.v2.User - */ -export declare class User extends Message { - /** - * @generated from field: int32 id = 1; - */ - id: number; - - /** - * @generated from field: memos.api.v2.RowStatus row_status = 2; - */ - rowStatus: RowStatus; - - /** - * @generated from field: int64 created_ts = 3; - */ - createdTs: bigint; - - /** - * @generated from field: int64 updated_ts = 4; - */ - updatedTs: bigint; - - /** - * @generated from field: string username = 5; - */ - username: string; - - /** - * @generated from field: memos.api.v2.Role role = 6; - */ - role: Role; - - /** - * @generated from field: string email = 7; - */ - email: string; - - /** - * @generated from field: string nickname = 8; - */ - nickname: string; - - /** - * @generated from field: string open_id = 9; - */ - openId: string; - - /** - * @generated from field: string avatar_url = 10; - */ - avatarUrl: string; - - constructor(data?: PartialMessage); - - static readonly runtime: typeof proto3; - static readonly typeName = "memos.api.v2.User"; - static readonly fields: FieldList; - - static fromBinary(bytes: Uint8Array, options?: Partial): User; - - static fromJson(jsonValue: JsonValue, options?: Partial): User; - - static fromJsonString(jsonString: string, options?: Partial): User; - - static equals(a: User | PlainMessage | undefined, b: User | PlainMessage | undefined): boolean; -} - /** * @generated from message memos.api.v2.GetUserRequest */ export declare class GetUserRequest extends Message { /** - * @generated from field: string name = 1; + * @generated from field: string username = 1; */ - name: string; + username: string; constructor(data?: PartialMessage); @@ -150,6 +155,66 @@ export declare class GetUserResponse extends Message { static equals(a: GetUserResponse | PlainMessage | undefined, b: GetUserResponse | PlainMessage | undefined): boolean; } +/** + * @generated from message memos.api.v2.UpdateUserRequest + */ +export declare class UpdateUserRequest extends Message { + /** + * @generated from field: string username = 1; + */ + username: string; + + /** + * @generated from field: memos.api.v2.User user = 2; + */ + user?: User; + + /** + * The update mask applies to the user resource. + * + * @generated from field: google.protobuf.FieldMask update_mask = 3; + */ + updateMask?: FieldMask; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "memos.api.v2.UpdateUserRequest"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): UpdateUserRequest; + + static fromJson(jsonValue: JsonValue, options?: Partial): UpdateUserRequest; + + static fromJsonString(jsonString: string, options?: Partial): UpdateUserRequest; + + static equals(a: UpdateUserRequest | PlainMessage | undefined, b: UpdateUserRequest | PlainMessage | undefined): boolean; +} + +/** + * @generated from message memos.api.v2.UpdateUserResponse + */ +export declare class UpdateUserResponse extends Message { + /** + * @generated from field: memos.api.v2.User user = 1; + */ + user?: User; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "memos.api.v2.UpdateUserResponse"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): UpdateUserResponse; + + static fromJson(jsonValue: JsonValue, options?: Partial): UpdateUserResponse; + + static fromJsonString(jsonString: string, options?: Partial): UpdateUserResponse; + + static equals(a: UpdateUserResponse | PlainMessage | undefined, b: UpdateUserResponse | PlainMessage | undefined): boolean; +} + /** * @generated from message memos.api.v2.UserSetting */ diff --git a/web/src/types/proto/api/v2/user_service_pb.js b/web/src/types/proto/api/v2/user_service_pb.js index c08be801..2658ec66 100644 --- a/web/src/types/proto/api/v2/user_service_pb.js +++ b/web/src/types/proto/api/v2/user_service_pb.js @@ -3,23 +3,10 @@ /* eslint-disable */ // @ts-nocheck -import { proto3 } from "@bufbuild/protobuf"; +import { FieldMask, proto3, Timestamp } from "@bufbuild/protobuf"; import { RowStatus } from "./common_pb.js"; import { Visibility } from "./memo_service_pb.js"; -/** - * @generated from enum memos.api.v2.Role - */ -export const Role = proto3.makeEnum( - "memos.api.v2.Role", - [ - {no: 0, name: "ROLE_UNSPECIFIED"}, - {no: 1, name: "HOST"}, - {no: 2, name: "ADMIN"}, - {no: 3, name: "USER"}, - ], -); - /** * @generated from message memos.api.v2.User */ @@ -28,14 +15,28 @@ export const User = proto3.makeMessageType( () => [ { no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ }, { no: 2, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) }, - { no: 3, name: "created_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ }, - { no: 4, name: "updated_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ }, + { no: 3, name: "create_time", kind: "message", T: Timestamp }, + { no: 4, name: "update_time", kind: "message", T: Timestamp }, { no: 5, name: "username", kind: "scalar", T: 9 /* ScalarType.STRING */ }, - { no: 6, name: "role", kind: "enum", T: proto3.getEnumType(Role) }, + { no: 6, name: "role", kind: "enum", T: proto3.getEnumType(User_Role) }, { no: 7, name: "email", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 8, name: "nickname", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 9, name: "open_id", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 10, name: "avatar_url", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 11, name: "password", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ], +); + +/** + * @generated from enum memos.api.v2.User.Role + */ +export const User_Role = proto3.makeEnum( + "memos.api.v2.User.Role", + [ + {no: 0, name: "ROLE_UNSPECIFIED"}, + {no: 1, name: "HOST"}, + {no: 2, name: "ADMIN"}, + {no: 3, name: "USER"}, ], ); @@ -45,7 +46,7 @@ export const User = proto3.makeMessageType( export const GetUserRequest = proto3.makeMessageType( "memos.api.v2.GetUserRequest", () => [ - { no: 1, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 1, name: "username", kind: "scalar", T: 9 /* ScalarType.STRING */ }, ], ); @@ -59,6 +60,28 @@ export const GetUserResponse = proto3.makeMessageType( ], ); +/** + * @generated from message memos.api.v2.UpdateUserRequest + */ +export const UpdateUserRequest = proto3.makeMessageType( + "memos.api.v2.UpdateUserRequest", + () => [ + { no: 1, name: "username", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "user", kind: "message", T: User }, + { no: 3, name: "update_mask", kind: "message", T: FieldMask }, + ], +); + +/** + * @generated from message memos.api.v2.UpdateUserResponse + */ +export const UpdateUserResponse = proto3.makeMessageType( + "memos.api.v2.UpdateUserResponse", + () => [ + { no: 1, name: "user", kind: "message", T: User }, + ], +); + /** * @generated from message memos.api.v2.UserSetting */