diff --git a/proto/api/v1/user_service.proto b/proto/api/v1/user_service.proto index d552e1b24..4505451ec 100644 --- a/proto/api/v1/user_service.proto +++ b/proto/api/v1/user_service.proto @@ -106,21 +106,6 @@ service UserService { option (google.api.method_signature) = "name"; } - // ListSessions returns a list of active login sessions for a user. - // Each session represents a browser/device where the user is logged in. - // Sessions are backed by refresh tokens with sliding expiration. - rpc ListSessions(ListSessionsRequest) returns (ListSessionsResponse) { - option (google.api.http) = {get: "/api/v1/{parent=users/*}/sessions"}; - option (google.api.method_signature) = "parent"; - } - - // RevokeSession revokes a specific login session. - // This invalidates the refresh token, forcing re-authentication on that device. - rpc RevokeSession(RevokeSessionRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=users/*/sessions/*}"}; - option (google.api.method_signature) = "name"; - } - // ListUserWebhooks returns a list of webhooks for a user. rpc ListUserWebhooks(ListUserWebhooksRequest) returns (ListUserWebhooksResponse) { option (google.api.http) = {get: "/api/v1/{parent=users/*}/webhooks"}; @@ -392,8 +377,6 @@ message UserSetting { oneof value { GeneralSetting general_setting = 2; - SessionsSetting sessions_setting = 3; - AccessTokensSetting access_tokens_setting = 4; WebhooksSetting webhooks_setting = 5; } @@ -402,10 +385,6 @@ message UserSetting { KEY_UNSPECIFIED = 0; // GENERAL is the key for general user settings. GENERAL = 1; - // SESSIONS is the key for user login sessions (refresh tokens). - SESSIONS = 2; - // ACCESS_TOKENS is the key for Personal Access Tokens (PATs). - ACCESS_TOKENS = 3; // WEBHOOKS is the key for user webhooks. WEBHOOKS = 4; } @@ -422,18 +401,6 @@ message UserSetting { string theme = 4 [(google.api.field_behavior) = OPTIONAL]; } - // User authentication sessions configuration. - message SessionsSetting { - // List of active login sessions. - repeated Session sessions = 1; - } - - // Personal access tokens configuration. - message AccessTokensSetting { - // List of personal access tokens (PATs). - repeated PersonalAccessToken personal_access_tokens = 1; - } - // User webhooks configuration. message WebhooksSetting { // List of user webhooks. @@ -577,70 +544,6 @@ message DeletePersonalAccessTokenRequest { ]; } -// Session represents a user's login session on a specific device/browser. -// Sessions are backed by refresh tokens with sliding expiration. -message Session { - option (google.api.resource) = { - type: "memos.api.v1/Session" - pattern: "users/{user}/sessions/{session}" - name_field: "name" - }; - - // The resource name of the session. - // Format: users/{user}/sessions/{session} - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // The session ID. - string session_id = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // The timestamp when the session was created. - google.protobuf.Timestamp create_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // The timestamp when the session was last accessed. - // Used for sliding expiration calculation (last_accessed_time + 2 weeks). - google.protobuf.Timestamp last_accessed_time = 4 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Client information associated with this session. - ClientInfo client_info = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; - - message ClientInfo { - // User agent string of the client. - string user_agent = 1; - - // IP address of the client. - string ip_address = 2; - - // Optional. Device type (e.g., "mobile", "desktop", "tablet"). - string device_type = 3 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. Operating system (e.g., "iOS 17.0", "Windows 11"). - string os = 4 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. Browser name and version (e.g., "Chrome 119.0"). - string browser = 5 [(google.api.field_behavior) = OPTIONAL]; - } -} - -message ListSessionsRequest { - // Required. The resource name of the parent. - // Format: users/{user} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; -} - -message ListSessionsResponse { - // The list of sessions. - repeated Session sessions = 1; -} - -message RevokeSessionRequest { - // The name of the session to revoke. - // Format: users/{user}/sessions/{session} - string name = 1 [(google.api.field_behavior) = REQUIRED]; -} - // UserWebhook represents a webhook owned by a user. message UserWebhook { // The name of the webhook. diff --git a/proto/gen/api/v1/apiv1connect/user_service.connect.go b/proto/gen/api/v1/apiv1connect/user_service.connect.go index e9034f940..bad608ffb 100644 --- a/proto/gen/api/v1/apiv1connect/user_service.connect.go +++ b/proto/gen/api/v1/apiv1connect/user_service.connect.go @@ -68,12 +68,6 @@ const ( // UserServiceDeletePersonalAccessTokenProcedure is the fully-qualified name of the UserService's // DeletePersonalAccessToken RPC. UserServiceDeletePersonalAccessTokenProcedure = "/memos.api.v1.UserService/DeletePersonalAccessToken" - // UserServiceListSessionsProcedure is the fully-qualified name of the UserService's ListSessions - // RPC. - UserServiceListSessionsProcedure = "/memos.api.v1.UserService/ListSessions" - // UserServiceRevokeSessionProcedure is the fully-qualified name of the UserService's RevokeSession - // RPC. - UserServiceRevokeSessionProcedure = "/memos.api.v1.UserService/RevokeSession" // UserServiceListUserWebhooksProcedure is the fully-qualified name of the UserService's // ListUserWebhooks RPC. UserServiceListUserWebhooksProcedure = "/memos.api.v1.UserService/ListUserWebhooks" @@ -130,13 +124,6 @@ type UserServiceClient interface { CreatePersonalAccessToken(context.Context, *connect.Request[v1.CreatePersonalAccessTokenRequest]) (*connect.Response[v1.CreatePersonalAccessTokenResponse], error) // DeletePersonalAccessToken deletes a Personal Access Token. DeletePersonalAccessToken(context.Context, *connect.Request[v1.DeletePersonalAccessTokenRequest]) (*connect.Response[emptypb.Empty], error) - // ListSessions returns a list of active login sessions for a user. - // Each session represents a browser/device where the user is logged in. - // Sessions are backed by refresh tokens with sliding expiration. - ListSessions(context.Context, *connect.Request[v1.ListSessionsRequest]) (*connect.Response[v1.ListSessionsResponse], error) - // RevokeSession revokes a specific login session. - // This invalidates the refresh token, forcing re-authentication on that device. - RevokeSession(context.Context, *connect.Request[v1.RevokeSessionRequest]) (*connect.Response[emptypb.Empty], error) // ListUserWebhooks returns a list of webhooks for a user. ListUserWebhooks(context.Context, *connect.Request[v1.ListUserWebhooksRequest]) (*connect.Response[v1.ListUserWebhooksResponse], error) // CreateUserWebhook creates a new webhook for a user. @@ -242,18 +229,6 @@ func NewUserServiceClient(httpClient connect.HTTPClient, baseURL string, opts .. connect.WithSchema(userServiceMethods.ByName("DeletePersonalAccessToken")), connect.WithClientOptions(opts...), ), - listSessions: connect.NewClient[v1.ListSessionsRequest, v1.ListSessionsResponse]( - httpClient, - baseURL+UserServiceListSessionsProcedure, - connect.WithSchema(userServiceMethods.ByName("ListSessions")), - connect.WithClientOptions(opts...), - ), - revokeSession: connect.NewClient[v1.RevokeSessionRequest, emptypb.Empty]( - httpClient, - baseURL+UserServiceRevokeSessionProcedure, - connect.WithSchema(userServiceMethods.ByName("RevokeSession")), - connect.WithClientOptions(opts...), - ), listUserWebhooks: connect.NewClient[v1.ListUserWebhooksRequest, v1.ListUserWebhooksResponse]( httpClient, baseURL+UserServiceListUserWebhooksProcedure, @@ -314,8 +289,6 @@ type userServiceClient struct { listPersonalAccessTokens *connect.Client[v1.ListPersonalAccessTokensRequest, v1.ListPersonalAccessTokensResponse] createPersonalAccessToken *connect.Client[v1.CreatePersonalAccessTokenRequest, v1.CreatePersonalAccessTokenResponse] deletePersonalAccessToken *connect.Client[v1.DeletePersonalAccessTokenRequest, emptypb.Empty] - listSessions *connect.Client[v1.ListSessionsRequest, v1.ListSessionsResponse] - revokeSession *connect.Client[v1.RevokeSessionRequest, emptypb.Empty] listUserWebhooks *connect.Client[v1.ListUserWebhooksRequest, v1.ListUserWebhooksResponse] createUserWebhook *connect.Client[v1.CreateUserWebhookRequest, v1.UserWebhook] updateUserWebhook *connect.Client[v1.UpdateUserWebhookRequest, v1.UserWebhook] @@ -390,16 +363,6 @@ func (c *userServiceClient) DeletePersonalAccessToken(ctx context.Context, req * return c.deletePersonalAccessToken.CallUnary(ctx, req) } -// ListSessions calls memos.api.v1.UserService.ListSessions. -func (c *userServiceClient) ListSessions(ctx context.Context, req *connect.Request[v1.ListSessionsRequest]) (*connect.Response[v1.ListSessionsResponse], error) { - return c.listSessions.CallUnary(ctx, req) -} - -// RevokeSession calls memos.api.v1.UserService.RevokeSession. -func (c *userServiceClient) RevokeSession(ctx context.Context, req *connect.Request[v1.RevokeSessionRequest]) (*connect.Response[emptypb.Empty], error) { - return c.revokeSession.CallUnary(ctx, req) -} - // ListUserWebhooks calls memos.api.v1.UserService.ListUserWebhooks. func (c *userServiceClient) ListUserWebhooks(ctx context.Context, req *connect.Request[v1.ListUserWebhooksRequest]) (*connect.Response[v1.ListUserWebhooksResponse], error) { return c.listUserWebhooks.CallUnary(ctx, req) @@ -468,13 +431,6 @@ type UserServiceHandler interface { CreatePersonalAccessToken(context.Context, *connect.Request[v1.CreatePersonalAccessTokenRequest]) (*connect.Response[v1.CreatePersonalAccessTokenResponse], error) // DeletePersonalAccessToken deletes a Personal Access Token. DeletePersonalAccessToken(context.Context, *connect.Request[v1.DeletePersonalAccessTokenRequest]) (*connect.Response[emptypb.Empty], error) - // ListSessions returns a list of active login sessions for a user. - // Each session represents a browser/device where the user is logged in. - // Sessions are backed by refresh tokens with sliding expiration. - ListSessions(context.Context, *connect.Request[v1.ListSessionsRequest]) (*connect.Response[v1.ListSessionsResponse], error) - // RevokeSession revokes a specific login session. - // This invalidates the refresh token, forcing re-authentication on that device. - RevokeSession(context.Context, *connect.Request[v1.RevokeSessionRequest]) (*connect.Response[emptypb.Empty], error) // ListUserWebhooks returns a list of webhooks for a user. ListUserWebhooks(context.Context, *connect.Request[v1.ListUserWebhooksRequest]) (*connect.Response[v1.ListUserWebhooksResponse], error) // CreateUserWebhook creates a new webhook for a user. @@ -576,18 +532,6 @@ func NewUserServiceHandler(svc UserServiceHandler, opts ...connect.HandlerOption connect.WithSchema(userServiceMethods.ByName("DeletePersonalAccessToken")), connect.WithHandlerOptions(opts...), ) - userServiceListSessionsHandler := connect.NewUnaryHandler( - UserServiceListSessionsProcedure, - svc.ListSessions, - connect.WithSchema(userServiceMethods.ByName("ListSessions")), - connect.WithHandlerOptions(opts...), - ) - userServiceRevokeSessionHandler := connect.NewUnaryHandler( - UserServiceRevokeSessionProcedure, - svc.RevokeSession, - connect.WithSchema(userServiceMethods.ByName("RevokeSession")), - connect.WithHandlerOptions(opts...), - ) userServiceListUserWebhooksHandler := connect.NewUnaryHandler( UserServiceListUserWebhooksProcedure, svc.ListUserWebhooks, @@ -658,10 +602,6 @@ func NewUserServiceHandler(svc UserServiceHandler, opts ...connect.HandlerOption userServiceCreatePersonalAccessTokenHandler.ServeHTTP(w, r) case UserServiceDeletePersonalAccessTokenProcedure: userServiceDeletePersonalAccessTokenHandler.ServeHTTP(w, r) - case UserServiceListSessionsProcedure: - userServiceListSessionsHandler.ServeHTTP(w, r) - case UserServiceRevokeSessionProcedure: - userServiceRevokeSessionHandler.ServeHTTP(w, r) case UserServiceListUserWebhooksProcedure: userServiceListUserWebhooksHandler.ServeHTTP(w, r) case UserServiceCreateUserWebhookProcedure: @@ -737,14 +677,6 @@ func (UnimplementedUserServiceHandler) DeletePersonalAccessToken(context.Context return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.DeletePersonalAccessToken is not implemented")) } -func (UnimplementedUserServiceHandler) ListSessions(context.Context, *connect.Request[v1.ListSessionsRequest]) (*connect.Response[v1.ListSessionsResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListSessions is not implemented")) -} - -func (UnimplementedUserServiceHandler) RevokeSession(context.Context, *connect.Request[v1.RevokeSessionRequest]) (*connect.Response[emptypb.Empty], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.RevokeSession is not implemented")) -} - func (UnimplementedUserServiceHandler) ListUserWebhooks(context.Context, *connect.Request[v1.ListUserWebhooksRequest]) (*connect.Response[v1.ListUserWebhooksResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListUserWebhooks is not implemented")) } diff --git a/proto/gen/api/v1/user_service.pb.go b/proto/gen/api/v1/user_service.pb.go index 031ef141c..82d76ad12 100644 --- a/proto/gen/api/v1/user_service.pb.go +++ b/proto/gen/api/v1/user_service.pb.go @@ -89,10 +89,6 @@ const ( UserSetting_KEY_UNSPECIFIED UserSetting_Key = 0 // GENERAL is the key for general user settings. UserSetting_GENERAL UserSetting_Key = 1 - // SESSIONS is the key for user login sessions (refresh tokens). - UserSetting_SESSIONS UserSetting_Key = 2 - // ACCESS_TOKENS is the key for Personal Access Tokens (PATs). - UserSetting_ACCESS_TOKENS UserSetting_Key = 3 // WEBHOOKS is the key for user webhooks. UserSetting_WEBHOOKS UserSetting_Key = 4 ) @@ -102,15 +98,11 @@ var ( UserSetting_Key_name = map[int32]string{ 0: "KEY_UNSPECIFIED", 1: "GENERAL", - 2: "SESSIONS", - 3: "ACCESS_TOKENS", 4: "WEBHOOKS", } UserSetting_Key_value = map[string]int32{ "KEY_UNSPECIFIED": 0, "GENERAL": 1, - "SESSIONS": 2, - "ACCESS_TOKENS": 3, "WEBHOOKS": 4, } ) @@ -188,7 +180,7 @@ func (x UserNotification_Status) Number() protoreflect.EnumNumber { // Deprecated: Use UserNotification_Status.Descriptor instead. func (UserNotification_Status) EnumDescriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{32, 0} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{28, 0} } type UserNotification_Type int32 @@ -234,7 +226,7 @@ func (x UserNotification_Type) Number() protoreflect.EnumNumber { // Deprecated: Use UserNotification_Type.Descriptor instead. func (UserNotification_Type) EnumDescriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{32, 1} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{28, 1} } type User struct { @@ -998,8 +990,6 @@ type UserSetting struct { // Types that are valid to be assigned to Value: // // *UserSetting_GeneralSetting_ - // *UserSetting_SessionsSetting_ - // *UserSetting_AccessTokensSetting_ // *UserSetting_WebhooksSetting_ Value isUserSetting_Value `protobuf_oneof:"value"` unknownFields protoimpl.UnknownFields @@ -1059,24 +1049,6 @@ func (x *UserSetting) GetGeneralSetting() *UserSetting_GeneralSetting { return nil } -func (x *UserSetting) GetSessionsSetting() *UserSetting_SessionsSetting { - if x != nil { - if x, ok := x.Value.(*UserSetting_SessionsSetting_); ok { - return x.SessionsSetting - } - } - return nil -} - -func (x *UserSetting) GetAccessTokensSetting() *UserSetting_AccessTokensSetting { - if x != nil { - if x, ok := x.Value.(*UserSetting_AccessTokensSetting_); ok { - return x.AccessTokensSetting - } - } - return nil -} - func (x *UserSetting) GetWebhooksSetting() *UserSetting_WebhooksSetting { if x != nil { if x, ok := x.Value.(*UserSetting_WebhooksSetting_); ok { @@ -1094,24 +1066,12 @@ type UserSetting_GeneralSetting_ struct { GeneralSetting *UserSetting_GeneralSetting `protobuf:"bytes,2,opt,name=general_setting,json=generalSetting,proto3,oneof"` } -type UserSetting_SessionsSetting_ struct { - SessionsSetting *UserSetting_SessionsSetting `protobuf:"bytes,3,opt,name=sessions_setting,json=sessionsSetting,proto3,oneof"` -} - -type UserSetting_AccessTokensSetting_ struct { - AccessTokensSetting *UserSetting_AccessTokensSetting `protobuf:"bytes,4,opt,name=access_tokens_setting,json=accessTokensSetting,proto3,oneof"` -} - type UserSetting_WebhooksSetting_ struct { WebhooksSetting *UserSetting_WebhooksSetting `protobuf:"bytes,5,opt,name=webhooks_setting,json=webhooksSetting,proto3,oneof"` } func (*UserSetting_GeneralSetting_) isUserSetting_Value() {} -func (*UserSetting_SessionsSetting_) isUserSetting_Value() {} - -func (*UserSetting_AccessTokensSetting_) isUserSetting_Value() {} - func (*UserSetting_WebhooksSetting_) isUserSetting_Value() {} type GetUserSettingRequest struct { @@ -1724,228 +1684,6 @@ func (x *DeletePersonalAccessTokenRequest) GetName() string { return "" } -// Session represents a user's login session on a specific device/browser. -// Sessions are backed by refresh tokens with sliding expiration. -type Session struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The resource name of the session. - // Format: users/{user}/sessions/{session} - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // The session ID. - SessionId string `protobuf:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` - // The timestamp when the session was created. - CreateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` - // The timestamp when the session was last accessed. - // Used for sliding expiration calculation (last_accessed_time + 2 weeks). - LastAccessedTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_accessed_time,json=lastAccessedTime,proto3" json:"last_accessed_time,omitempty"` - // Client information associated with this session. - ClientInfo *Session_ClientInfo `protobuf:"bytes,5,opt,name=client_info,json=clientInfo,proto3" json:"client_info,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Session) Reset() { - *x = Session{} - mi := &file_api_v1_user_service_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Session) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Session) ProtoMessage() {} - -func (x *Session) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[22] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Session.ProtoReflect.Descriptor instead. -func (*Session) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{22} -} - -func (x *Session) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Session) GetSessionId() string { - if x != nil { - return x.SessionId - } - return "" -} - -func (x *Session) GetCreateTime() *timestamppb.Timestamp { - if x != nil { - return x.CreateTime - } - return nil -} - -func (x *Session) GetLastAccessedTime() *timestamppb.Timestamp { - if x != nil { - return x.LastAccessedTime - } - return nil -} - -func (x *Session) GetClientInfo() *Session_ClientInfo { - if x != nil { - return x.ClientInfo - } - return nil -} - -type ListSessionsRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Required. The resource name of the parent. - // Format: users/{user} - Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ListSessionsRequest) Reset() { - *x = ListSessionsRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ListSessionsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListSessionsRequest) ProtoMessage() {} - -func (x *ListSessionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[23] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListSessionsRequest.ProtoReflect.Descriptor instead. -func (*ListSessionsRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{23} -} - -func (x *ListSessionsRequest) GetParent() string { - if x != nil { - return x.Parent - } - return "" -} - -type ListSessionsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The list of sessions. - Sessions []*Session `protobuf:"bytes,1,rep,name=sessions,proto3" json:"sessions,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ListSessionsResponse) Reset() { - *x = ListSessionsResponse{} - mi := &file_api_v1_user_service_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ListSessionsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListSessionsResponse) ProtoMessage() {} - -func (x *ListSessionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[24] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListSessionsResponse.ProtoReflect.Descriptor instead. -func (*ListSessionsResponse) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{24} -} - -func (x *ListSessionsResponse) GetSessions() []*Session { - if x != nil { - return x.Sessions - } - return nil -} - -type RevokeSessionRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The name of the session to revoke. - // Format: users/{user}/sessions/{session} - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *RevokeSessionRequest) Reset() { - *x = RevokeSessionRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *RevokeSessionRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RevokeSessionRequest) ProtoMessage() {} - -func (x *RevokeSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[25] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RevokeSessionRequest.ProtoReflect.Descriptor instead. -func (*RevokeSessionRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{25} -} - -func (x *RevokeSessionRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - // UserWebhook represents a webhook owned by a user. type UserWebhook struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1966,7 +1704,7 @@ type UserWebhook struct { func (x *UserWebhook) Reset() { *x = UserWebhook{} - mi := &file_api_v1_user_service_proto_msgTypes[26] + mi := &file_api_v1_user_service_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1978,7 +1716,7 @@ func (x *UserWebhook) String() string { func (*UserWebhook) ProtoMessage() {} func (x *UserWebhook) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[26] + mi := &file_api_v1_user_service_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1991,7 +1729,7 @@ func (x *UserWebhook) ProtoReflect() protoreflect.Message { // Deprecated: Use UserWebhook.ProtoReflect.Descriptor instead. func (*UserWebhook) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{26} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{22} } func (x *UserWebhook) GetName() string { @@ -2040,7 +1778,7 @@ type ListUserWebhooksRequest struct { func (x *ListUserWebhooksRequest) Reset() { *x = ListUserWebhooksRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[27] + mi := &file_api_v1_user_service_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2052,7 +1790,7 @@ func (x *ListUserWebhooksRequest) String() string { func (*ListUserWebhooksRequest) ProtoMessage() {} func (x *ListUserWebhooksRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[27] + mi := &file_api_v1_user_service_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2065,7 +1803,7 @@ func (x *ListUserWebhooksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUserWebhooksRequest.ProtoReflect.Descriptor instead. func (*ListUserWebhooksRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{27} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{23} } func (x *ListUserWebhooksRequest) GetParent() string { @@ -2085,7 +1823,7 @@ type ListUserWebhooksResponse struct { func (x *ListUserWebhooksResponse) Reset() { *x = ListUserWebhooksResponse{} - mi := &file_api_v1_user_service_proto_msgTypes[28] + mi := &file_api_v1_user_service_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2097,7 +1835,7 @@ func (x *ListUserWebhooksResponse) String() string { func (*ListUserWebhooksResponse) ProtoMessage() {} func (x *ListUserWebhooksResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[28] + mi := &file_api_v1_user_service_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2110,7 +1848,7 @@ func (x *ListUserWebhooksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUserWebhooksResponse.ProtoReflect.Descriptor instead. func (*ListUserWebhooksResponse) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{28} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{24} } func (x *ListUserWebhooksResponse) GetWebhooks() []*UserWebhook { @@ -2133,7 +1871,7 @@ type CreateUserWebhookRequest struct { func (x *CreateUserWebhookRequest) Reset() { *x = CreateUserWebhookRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[29] + mi := &file_api_v1_user_service_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2145,7 +1883,7 @@ func (x *CreateUserWebhookRequest) String() string { func (*CreateUserWebhookRequest) ProtoMessage() {} func (x *CreateUserWebhookRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[29] + mi := &file_api_v1_user_service_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2158,7 +1896,7 @@ func (x *CreateUserWebhookRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateUserWebhookRequest.ProtoReflect.Descriptor instead. func (*CreateUserWebhookRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{29} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{25} } func (x *CreateUserWebhookRequest) GetParent() string { @@ -2187,7 +1925,7 @@ type UpdateUserWebhookRequest struct { func (x *UpdateUserWebhookRequest) Reset() { *x = UpdateUserWebhookRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[30] + mi := &file_api_v1_user_service_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2199,7 +1937,7 @@ func (x *UpdateUserWebhookRequest) String() string { func (*UpdateUserWebhookRequest) ProtoMessage() {} func (x *UpdateUserWebhookRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[30] + mi := &file_api_v1_user_service_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2212,7 +1950,7 @@ func (x *UpdateUserWebhookRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserWebhookRequest.ProtoReflect.Descriptor instead. func (*UpdateUserWebhookRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{30} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{26} } func (x *UpdateUserWebhookRequest) GetWebhook() *UserWebhook { @@ -2240,7 +1978,7 @@ type DeleteUserWebhookRequest struct { func (x *DeleteUserWebhookRequest) Reset() { *x = DeleteUserWebhookRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[31] + mi := &file_api_v1_user_service_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2252,7 +1990,7 @@ func (x *DeleteUserWebhookRequest) String() string { func (*DeleteUserWebhookRequest) ProtoMessage() {} func (x *DeleteUserWebhookRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[31] + mi := &file_api_v1_user_service_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2265,7 +2003,7 @@ func (x *DeleteUserWebhookRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteUserWebhookRequest.ProtoReflect.Descriptor instead. func (*DeleteUserWebhookRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{31} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{27} } func (x *DeleteUserWebhookRequest) GetName() string { @@ -2297,7 +2035,7 @@ type UserNotification struct { func (x *UserNotification) Reset() { *x = UserNotification{} - mi := &file_api_v1_user_service_proto_msgTypes[32] + mi := &file_api_v1_user_service_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2309,7 +2047,7 @@ func (x *UserNotification) String() string { func (*UserNotification) ProtoMessage() {} func (x *UserNotification) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[32] + mi := &file_api_v1_user_service_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2322,7 +2060,7 @@ func (x *UserNotification) ProtoReflect() protoreflect.Message { // Deprecated: Use UserNotification.ProtoReflect.Descriptor instead. func (*UserNotification) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{32} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{28} } func (x *UserNotification) GetName() string { @@ -2381,7 +2119,7 @@ type ListUserNotificationsRequest struct { func (x *ListUserNotificationsRequest) Reset() { *x = ListUserNotificationsRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[33] + mi := &file_api_v1_user_service_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2393,7 +2131,7 @@ func (x *ListUserNotificationsRequest) String() string { func (*ListUserNotificationsRequest) ProtoMessage() {} func (x *ListUserNotificationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[33] + mi := &file_api_v1_user_service_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2406,7 +2144,7 @@ func (x *ListUserNotificationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUserNotificationsRequest.ProtoReflect.Descriptor instead. func (*ListUserNotificationsRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{33} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{29} } func (x *ListUserNotificationsRequest) GetParent() string { @@ -2447,7 +2185,7 @@ type ListUserNotificationsResponse struct { func (x *ListUserNotificationsResponse) Reset() { *x = ListUserNotificationsResponse{} - mi := &file_api_v1_user_service_proto_msgTypes[34] + mi := &file_api_v1_user_service_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2459,7 +2197,7 @@ func (x *ListUserNotificationsResponse) String() string { func (*ListUserNotificationsResponse) ProtoMessage() {} func (x *ListUserNotificationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[34] + mi := &file_api_v1_user_service_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2472,7 +2210,7 @@ func (x *ListUserNotificationsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUserNotificationsResponse.ProtoReflect.Descriptor instead. func (*ListUserNotificationsResponse) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{34} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{30} } func (x *ListUserNotificationsResponse) GetNotifications() []*UserNotification { @@ -2499,7 +2237,7 @@ type UpdateUserNotificationRequest struct { func (x *UpdateUserNotificationRequest) Reset() { *x = UpdateUserNotificationRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[35] + mi := &file_api_v1_user_service_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2511,7 +2249,7 @@ func (x *UpdateUserNotificationRequest) String() string { func (*UpdateUserNotificationRequest) ProtoMessage() {} func (x *UpdateUserNotificationRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[35] + mi := &file_api_v1_user_service_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2524,7 +2262,7 @@ func (x *UpdateUserNotificationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserNotificationRequest.ProtoReflect.Descriptor instead. func (*UpdateUserNotificationRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{35} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{31} } func (x *UpdateUserNotificationRequest) GetNotification() *UserNotification { @@ -2551,7 +2289,7 @@ type DeleteUserNotificationRequest struct { func (x *DeleteUserNotificationRequest) Reset() { *x = DeleteUserNotificationRequest{} - mi := &file_api_v1_user_service_proto_msgTypes[36] + mi := &file_api_v1_user_service_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2563,7 +2301,7 @@ func (x *DeleteUserNotificationRequest) String() string { func (*DeleteUserNotificationRequest) ProtoMessage() {} func (x *DeleteUserNotificationRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[36] + mi := &file_api_v1_user_service_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2576,7 +2314,7 @@ func (x *DeleteUserNotificationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteUserNotificationRequest.ProtoReflect.Descriptor instead. func (*DeleteUserNotificationRequest) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{36} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{32} } func (x *DeleteUserNotificationRequest) GetName() string { @@ -2599,7 +2337,7 @@ type UserStats_MemoTypeStats struct { func (x *UserStats_MemoTypeStats) Reset() { *x = UserStats_MemoTypeStats{} - mi := &file_api_v1_user_service_proto_msgTypes[38] + mi := &file_api_v1_user_service_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2611,7 +2349,7 @@ func (x *UserStats_MemoTypeStats) String() string { func (*UserStats_MemoTypeStats) ProtoMessage() {} func (x *UserStats_MemoTypeStats) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[38] + mi := &file_api_v1_user_service_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2672,7 +2410,7 @@ type UserSetting_GeneralSetting struct { func (x *UserSetting_GeneralSetting) Reset() { *x = UserSetting_GeneralSetting{} - mi := &file_api_v1_user_service_proto_msgTypes[39] + mi := &file_api_v1_user_service_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2684,7 +2422,7 @@ func (x *UserSetting_GeneralSetting) String() string { func (*UserSetting_GeneralSetting) ProtoMessage() {} func (x *UserSetting_GeneralSetting) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[39] + mi := &file_api_v1_user_service_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2721,98 +2459,6 @@ func (x *UserSetting_GeneralSetting) GetTheme() string { return "" } -// User authentication sessions configuration. -type UserSetting_SessionsSetting struct { - state protoimpl.MessageState `protogen:"open.v1"` - // List of active login sessions. - Sessions []*Session `protobuf:"bytes,1,rep,name=sessions,proto3" json:"sessions,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UserSetting_SessionsSetting) Reset() { - *x = UserSetting_SessionsSetting{} - mi := &file_api_v1_user_service_proto_msgTypes[40] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UserSetting_SessionsSetting) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserSetting_SessionsSetting) ProtoMessage() {} - -func (x *UserSetting_SessionsSetting) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[40] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UserSetting_SessionsSetting.ProtoReflect.Descriptor instead. -func (*UserSetting_SessionsSetting) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{11, 1} -} - -func (x *UserSetting_SessionsSetting) GetSessions() []*Session { - if x != nil { - return x.Sessions - } - return nil -} - -// Personal access tokens configuration. -type UserSetting_AccessTokensSetting struct { - state protoimpl.MessageState `protogen:"open.v1"` - // List of personal access tokens (PATs). - PersonalAccessTokens []*PersonalAccessToken `protobuf:"bytes,1,rep,name=personal_access_tokens,json=personalAccessTokens,proto3" json:"personal_access_tokens,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UserSetting_AccessTokensSetting) Reset() { - *x = UserSetting_AccessTokensSetting{} - mi := &file_api_v1_user_service_proto_msgTypes[41] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UserSetting_AccessTokensSetting) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserSetting_AccessTokensSetting) ProtoMessage() {} - -func (x *UserSetting_AccessTokensSetting) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[41] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UserSetting_AccessTokensSetting.ProtoReflect.Descriptor instead. -func (*UserSetting_AccessTokensSetting) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{11, 2} -} - -func (x *UserSetting_AccessTokensSetting) GetPersonalAccessTokens() []*PersonalAccessToken { - if x != nil { - return x.PersonalAccessTokens - } - return nil -} - // User webhooks configuration. type UserSetting_WebhooksSetting struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -2824,7 +2470,7 @@ type UserSetting_WebhooksSetting struct { func (x *UserSetting_WebhooksSetting) Reset() { *x = UserSetting_WebhooksSetting{} - mi := &file_api_v1_user_service_proto_msgTypes[42] + mi := &file_api_v1_user_service_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2836,7 +2482,7 @@ func (x *UserSetting_WebhooksSetting) String() string { func (*UserSetting_WebhooksSetting) ProtoMessage() {} func (x *UserSetting_WebhooksSetting) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[42] + mi := &file_api_v1_user_service_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2849,7 +2495,7 @@ func (x *UserSetting_WebhooksSetting) ProtoReflect() protoreflect.Message { // Deprecated: Use UserSetting_WebhooksSetting.ProtoReflect.Descriptor instead. func (*UserSetting_WebhooksSetting) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{11, 3} + return file_api_v1_user_service_proto_rawDescGZIP(), []int{11, 1} } func (x *UserSetting_WebhooksSetting) GetWebhooks() []*UserWebhook { @@ -2859,87 +2505,6 @@ func (x *UserSetting_WebhooksSetting) GetWebhooks() []*UserWebhook { return nil } -type Session_ClientInfo struct { - state protoimpl.MessageState `protogen:"open.v1"` - // User agent string of the client. - UserAgent string `protobuf:"bytes,1,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"` - // IP address of the client. - IpAddress string `protobuf:"bytes,2,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - // Optional. Device type (e.g., "mobile", "desktop", "tablet"). - DeviceType string `protobuf:"bytes,3,opt,name=device_type,json=deviceType,proto3" json:"device_type,omitempty"` - // Optional. Operating system (e.g., "iOS 17.0", "Windows 11"). - Os string `protobuf:"bytes,4,opt,name=os,proto3" json:"os,omitempty"` - // Optional. Browser name and version (e.g., "Chrome 119.0"). - Browser string `protobuf:"bytes,5,opt,name=browser,proto3" json:"browser,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Session_ClientInfo) Reset() { - *x = Session_ClientInfo{} - mi := &file_api_v1_user_service_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Session_ClientInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Session_ClientInfo) ProtoMessage() {} - -func (x *Session_ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[43] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Session_ClientInfo.ProtoReflect.Descriptor instead. -func (*Session_ClientInfo) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{22, 0} -} - -func (x *Session_ClientInfo) GetUserAgent() string { - if x != nil { - return x.UserAgent - } - return "" -} - -func (x *Session_ClientInfo) GetIpAddress() string { - if x != nil { - return x.IpAddress - } - return "" -} - -func (x *Session_ClientInfo) GetDeviceType() string { - if x != nil { - return x.DeviceType - } - return "" -} - -func (x *Session_ClientInfo) GetOs() string { - if x != nil { - return x.Os - } - return "" -} - -func (x *Session_ClientInfo) GetBrowser() string { - if x != nil { - return x.Browser - } - return "" -} - var File_api_v1_user_service_proto protoreflect.FileDescriptor const file_api_v1_user_service_proto_rawDesc = "" + @@ -3022,28 +2587,20 @@ const file_api_v1_user_service_proto_rawDesc = "" + "\x11memos.api.v1/UserR\x04name\"\x19\n" + "\x17ListAllUserStatsRequest\"I\n" + "\x18ListAllUserStatsResponse\x12-\n" + - "\x05stats\x18\x01 \x03(\v2\x17.memos.api.v1.UserStatsR\x05stats\"\xc4\a\n" + + "\x05stats\x18\x01 \x03(\v2\x17.memos.api.v1.UserStatsR\x05stats\"\xb0\x04\n" + "\vUserSetting\x12\x17\n" + "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12S\n" + "\x0fgeneral_setting\x18\x02 \x01(\v2(.memos.api.v1.UserSetting.GeneralSettingH\x00R\x0egeneralSetting\x12V\n" + - "\x10sessions_setting\x18\x03 \x01(\v2).memos.api.v1.UserSetting.SessionsSettingH\x00R\x0fsessionsSetting\x12c\n" + - "\x15access_tokens_setting\x18\x04 \x01(\v2-.memos.api.v1.UserSetting.AccessTokensSettingH\x00R\x13accessTokensSetting\x12V\n" + "\x10webhooks_setting\x18\x05 \x01(\v2).memos.api.v1.UserSetting.WebhooksSettingH\x00R\x0fwebhooksSetting\x1av\n" + "\x0eGeneralSetting\x12\x1b\n" + "\x06locale\x18\x01 \x01(\tB\x03\xe0A\x01R\x06locale\x12,\n" + "\x0fmemo_visibility\x18\x03 \x01(\tB\x03\xe0A\x01R\x0ememoVisibility\x12\x19\n" + - "\x05theme\x18\x04 \x01(\tB\x03\xe0A\x01R\x05theme\x1aD\n" + - "\x0fSessionsSetting\x121\n" + - "\bsessions\x18\x01 \x03(\v2\x15.memos.api.v1.SessionR\bsessions\x1an\n" + - "\x13AccessTokensSetting\x12W\n" + - "\x16personal_access_tokens\x18\x01 \x03(\v2!.memos.api.v1.PersonalAccessTokenR\x14personalAccessTokens\x1aH\n" + + "\x05theme\x18\x04 \x01(\tB\x03\xe0A\x01R\x05theme\x1aH\n" + "\x0fWebhooksSetting\x125\n" + - "\bwebhooks\x18\x01 \x03(\v2\x19.memos.api.v1.UserWebhookR\bwebhooks\"V\n" + + "\bwebhooks\x18\x01 \x03(\v2\x19.memos.api.v1.UserWebhookR\bwebhooks\"5\n" + "\x03Key\x12\x13\n" + "\x0fKEY_UNSPECIFIED\x10\x00\x12\v\n" + "\aGENERAL\x10\x01\x12\f\n" + - "\bSESSIONS\x10\x02\x12\x11\n" + - "\rACCESS_TOKENS\x10\x03\x12\f\n" + "\bWEBHOOKS\x10\x04:Y\xeaAV\n" + "\x18memos.api.v1/UserSetting\x12\x1fusers/{user}/settings/{setting}*\fuserSettings2\vuserSettingB\a\n" + "\x05value\"M\n" + @@ -3096,34 +2653,7 @@ const file_api_v1_user_service_proto_rawDesc = "" + "\x05token\x18\x02 \x01(\tR\x05token\"`\n" + " DeletePersonalAccessTokenRequest\x12<\n" + "\x04name\x18\x01 \x01(\tB(\xe0A\x02\xfaA\"\n" + - " memos.api.v1/PersonalAccessTokenR\x04name\"\x88\x04\n" + - "\aSession\x12\x17\n" + - "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12\"\n" + - "\n" + - "session_id\x18\x02 \x01(\tB\x03\xe0A\x03R\tsessionId\x12@\n" + - "\vcreate_time\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\n" + - "createTime\x12M\n" + - "\x12last_accessed_time\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\x10lastAccessedTime\x12F\n" + - "\vclient_info\x18\x05 \x01(\v2 .memos.api.v1.Session.ClientInfoB\x03\xe0A\x03R\n" + - "clientInfo\x1a\xa4\x01\n" + - "\n" + - "ClientInfo\x12\x1d\n" + - "\n" + - "user_agent\x18\x01 \x01(\tR\tuserAgent\x12\x1d\n" + - "\n" + - "ip_address\x18\x02 \x01(\tR\tipAddress\x12$\n" + - "\vdevice_type\x18\x03 \x01(\tB\x03\xe0A\x01R\n" + - "deviceType\x12\x13\n" + - "\x02os\x18\x04 \x01(\tB\x03\xe0A\x01R\x02os\x12\x1d\n" + - "\abrowser\x18\x05 \x01(\tB\x03\xe0A\x01R\abrowser:@\xeaA=\n" + - "\x14memos.api.v1/Session\x12\x1fusers/{user}/sessions/{session}\x1a\x04name\"H\n" + - "\x13ListSessionsRequest\x121\n" + - "\x06parent\x18\x01 \x01(\tB\x19\xe0A\x02\xfaA\x13\n" + - "\x11memos.api.v1/UserR\x06parent\"I\n" + - "\x14ListSessionsResponse\x121\n" + - "\bsessions\x18\x01 \x03(\v2\x15.memos.api.v1.SessionR\bsessions\"/\n" + - "\x14RevokeSessionRequest\x12\x17\n" + - "\x04name\x18\x01 \x01(\tB\x03\xe0A\x02R\x04name\"\xda\x01\n" + + " memos.api.v1/PersonalAccessTokenR\x04name\"\xda\x01\n" + "\vUserWebhook\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n" + "\x03url\x18\x02 \x01(\tR\x03url\x12!\n" + @@ -3181,7 +2711,7 @@ const file_api_v1_user_service_proto_rawDesc = "" + "updateMask\"Z\n" + "\x1dDeleteUserNotificationRequest\x129\n" + "\x04name\x18\x01 \x01(\tB%\xe0A\x02\xfaA\x1f\n" + - "\x1dmemos.api.v1/UserNotificationR\x04name2\x8e\x19\n" + + "\x1dmemos.api.v1/UserNotificationR\x04name2\x83\x17\n" + "\vUserService\x12c\n" + "\tListUsers\x12\x1e.memos.api.v1.ListUsersRequest\x1a\x1f.memos.api.v1.ListUsersResponse\"\x15\x82\xd3\xe4\x93\x02\x0f\x12\r/api/v1/users\x12b\n" + "\aGetUser\x12\x1c.memos.api.v1.GetUserRequest\x1a\x12.memos.api.v1.User\"%\xdaA\x04name\x82\xd3\xe4\x93\x02\x18\x12\x16/api/v1/{name=users/*}\x12e\n" + @@ -3198,9 +2728,7 @@ const file_api_v1_user_service_proto_rawDesc = "" + "\x10ListUserSettings\x12%.memos.api.v1.ListUserSettingsRequest\x1a&.memos.api.v1.ListUserSettingsResponse\"2\xdaA\x06parent\x82\xd3\xe4\x93\x02#\x12!/api/v1/{parent=users/*}/settings\x12\xb9\x01\n" + "\x18ListPersonalAccessTokens\x12-.memos.api.v1.ListPersonalAccessTokensRequest\x1a..memos.api.v1.ListPersonalAccessTokensResponse\">\xdaA\x06parent\x82\xd3\xe4\x93\x02/\x12-/api/v1/{parent=users/*}/personalAccessTokens\x12\xb6\x01\n" + "\x19CreatePersonalAccessToken\x12..memos.api.v1.CreatePersonalAccessTokenRequest\x1a/.memos.api.v1.CreatePersonalAccessTokenResponse\"8\x82\xd3\xe4\x93\x022:\x01*\"-/api/v1/{parent=users/*}/personalAccessTokens\x12\xa1\x01\n" + - "\x19DeletePersonalAccessToken\x12..memos.api.v1.DeletePersonalAccessTokenRequest\x1a\x16.google.protobuf.Empty\"<\xdaA\x04name\x82\xd3\xe4\x93\x02/*-/api/v1/{name=users/*/personalAccessTokens/*}\x12\x89\x01\n" + - "\fListSessions\x12!.memos.api.v1.ListSessionsRequest\x1a\".memos.api.v1.ListSessionsResponse\"2\xdaA\x06parent\x82\xd3\xe4\x93\x02#\x12!/api/v1/{parent=users/*}/sessions\x12}\n" + - "\rRevokeSession\x12\".memos.api.v1.RevokeSessionRequest\x1a\x16.google.protobuf.Empty\"0\xdaA\x04name\x82\xd3\xe4\x93\x02#*!/api/v1/{name=users/*/sessions/*}\x12\x95\x01\n" + + "\x19DeletePersonalAccessToken\x12..memos.api.v1.DeletePersonalAccessTokenRequest\x1a\x16.google.protobuf.Empty\"<\xdaA\x04name\x82\xd3\xe4\x93\x02/*-/api/v1/{name=users/*/personalAccessTokens/*}\x12\x95\x01\n" + "\x10ListUserWebhooks\x12%.memos.api.v1.ListUserWebhooksRequest\x1a&.memos.api.v1.ListUserWebhooksResponse\"2\xdaA\x06parent\x82\xd3\xe4\x93\x02#\x12!/api/v1/{parent=users/*}/webhooks\x12\x9b\x01\n" + "\x11CreateUserWebhook\x12&.memos.api.v1.CreateUserWebhookRequest\x1a\x19.memos.api.v1.UserWebhook\"C\xdaA\x0eparent,webhook\x82\xd3\xe4\x93\x02,:\awebhook\"!/api/v1/{parent=users/*}/webhooks\x12\xa8\x01\n" + "\x11UpdateUserWebhook\x12&.memos.api.v1.UpdateUserWebhookRequest\x1a\x19.memos.api.v1.UserWebhook\"P\xdaA\x13webhook,update_mask\x82\xd3\xe4\x93\x024:\awebhook2)/api/v1/{webhook.name=users/*/webhooks/*}\x12\x85\x01\n" + @@ -3223,7 +2751,7 @@ func file_api_v1_user_service_proto_rawDescGZIP() []byte { } var file_api_v1_user_service_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_api_v1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 44) +var file_api_v1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 37) var file_api_v1_user_service_proto_goTypes = []any{ (User_Role)(0), // 0: memos.api.v1.User.Role (UserSetting_Key)(0), // 1: memos.api.v1.UserSetting.Key @@ -3251,127 +2779,108 @@ var file_api_v1_user_service_proto_goTypes = []any{ (*CreatePersonalAccessTokenRequest)(nil), // 23: memos.api.v1.CreatePersonalAccessTokenRequest (*CreatePersonalAccessTokenResponse)(nil), // 24: memos.api.v1.CreatePersonalAccessTokenResponse (*DeletePersonalAccessTokenRequest)(nil), // 25: memos.api.v1.DeletePersonalAccessTokenRequest - (*Session)(nil), // 26: memos.api.v1.Session - (*ListSessionsRequest)(nil), // 27: memos.api.v1.ListSessionsRequest - (*ListSessionsResponse)(nil), // 28: memos.api.v1.ListSessionsResponse - (*RevokeSessionRequest)(nil), // 29: memos.api.v1.RevokeSessionRequest - (*UserWebhook)(nil), // 30: memos.api.v1.UserWebhook - (*ListUserWebhooksRequest)(nil), // 31: memos.api.v1.ListUserWebhooksRequest - (*ListUserWebhooksResponse)(nil), // 32: memos.api.v1.ListUserWebhooksResponse - (*CreateUserWebhookRequest)(nil), // 33: memos.api.v1.CreateUserWebhookRequest - (*UpdateUserWebhookRequest)(nil), // 34: memos.api.v1.UpdateUserWebhookRequest - (*DeleteUserWebhookRequest)(nil), // 35: memos.api.v1.DeleteUserWebhookRequest - (*UserNotification)(nil), // 36: memos.api.v1.UserNotification - (*ListUserNotificationsRequest)(nil), // 37: memos.api.v1.ListUserNotificationsRequest - (*ListUserNotificationsResponse)(nil), // 38: memos.api.v1.ListUserNotificationsResponse - (*UpdateUserNotificationRequest)(nil), // 39: memos.api.v1.UpdateUserNotificationRequest - (*DeleteUserNotificationRequest)(nil), // 40: memos.api.v1.DeleteUserNotificationRequest - nil, // 41: memos.api.v1.UserStats.TagCountEntry - (*UserStats_MemoTypeStats)(nil), // 42: memos.api.v1.UserStats.MemoTypeStats - (*UserSetting_GeneralSetting)(nil), // 43: memos.api.v1.UserSetting.GeneralSetting - (*UserSetting_SessionsSetting)(nil), // 44: memos.api.v1.UserSetting.SessionsSetting - (*UserSetting_AccessTokensSetting)(nil), // 45: memos.api.v1.UserSetting.AccessTokensSetting - (*UserSetting_WebhooksSetting)(nil), // 46: memos.api.v1.UserSetting.WebhooksSetting - (*Session_ClientInfo)(nil), // 47: memos.api.v1.Session.ClientInfo - (State)(0), // 48: memos.api.v1.State - (*timestamppb.Timestamp)(nil), // 49: google.protobuf.Timestamp - (*fieldmaskpb.FieldMask)(nil), // 50: google.protobuf.FieldMask - (*emptypb.Empty)(nil), // 51: google.protobuf.Empty + (*UserWebhook)(nil), // 26: memos.api.v1.UserWebhook + (*ListUserWebhooksRequest)(nil), // 27: memos.api.v1.ListUserWebhooksRequest + (*ListUserWebhooksResponse)(nil), // 28: memos.api.v1.ListUserWebhooksResponse + (*CreateUserWebhookRequest)(nil), // 29: memos.api.v1.CreateUserWebhookRequest + (*UpdateUserWebhookRequest)(nil), // 30: memos.api.v1.UpdateUserWebhookRequest + (*DeleteUserWebhookRequest)(nil), // 31: memos.api.v1.DeleteUserWebhookRequest + (*UserNotification)(nil), // 32: memos.api.v1.UserNotification + (*ListUserNotificationsRequest)(nil), // 33: memos.api.v1.ListUserNotificationsRequest + (*ListUserNotificationsResponse)(nil), // 34: memos.api.v1.ListUserNotificationsResponse + (*UpdateUserNotificationRequest)(nil), // 35: memos.api.v1.UpdateUserNotificationRequest + (*DeleteUserNotificationRequest)(nil), // 36: memos.api.v1.DeleteUserNotificationRequest + nil, // 37: memos.api.v1.UserStats.TagCountEntry + (*UserStats_MemoTypeStats)(nil), // 38: memos.api.v1.UserStats.MemoTypeStats + (*UserSetting_GeneralSetting)(nil), // 39: memos.api.v1.UserSetting.GeneralSetting + (*UserSetting_WebhooksSetting)(nil), // 40: memos.api.v1.UserSetting.WebhooksSetting + (State)(0), // 41: memos.api.v1.State + (*timestamppb.Timestamp)(nil), // 42: google.protobuf.Timestamp + (*fieldmaskpb.FieldMask)(nil), // 43: google.protobuf.FieldMask + (*emptypb.Empty)(nil), // 44: google.protobuf.Empty } var file_api_v1_user_service_proto_depIdxs = []int32{ 0, // 0: memos.api.v1.User.role:type_name -> memos.api.v1.User.Role - 48, // 1: memos.api.v1.User.state:type_name -> memos.api.v1.State - 49, // 2: memos.api.v1.User.create_time:type_name -> google.protobuf.Timestamp - 49, // 3: memos.api.v1.User.update_time:type_name -> google.protobuf.Timestamp + 41, // 1: memos.api.v1.User.state:type_name -> memos.api.v1.State + 42, // 2: memos.api.v1.User.create_time:type_name -> google.protobuf.Timestamp + 42, // 3: memos.api.v1.User.update_time:type_name -> google.protobuf.Timestamp 4, // 4: memos.api.v1.ListUsersResponse.users:type_name -> memos.api.v1.User - 50, // 5: memos.api.v1.GetUserRequest.read_mask:type_name -> google.protobuf.FieldMask + 43, // 5: memos.api.v1.GetUserRequest.read_mask:type_name -> google.protobuf.FieldMask 4, // 6: memos.api.v1.CreateUserRequest.user:type_name -> memos.api.v1.User 4, // 7: memos.api.v1.UpdateUserRequest.user:type_name -> memos.api.v1.User - 50, // 8: memos.api.v1.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask - 49, // 9: memos.api.v1.UserStats.memo_display_timestamps:type_name -> google.protobuf.Timestamp - 42, // 10: memos.api.v1.UserStats.memo_type_stats:type_name -> memos.api.v1.UserStats.MemoTypeStats - 41, // 11: memos.api.v1.UserStats.tag_count:type_name -> memos.api.v1.UserStats.TagCountEntry + 43, // 8: memos.api.v1.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask + 42, // 9: memos.api.v1.UserStats.memo_display_timestamps:type_name -> google.protobuf.Timestamp + 38, // 10: memos.api.v1.UserStats.memo_type_stats:type_name -> memos.api.v1.UserStats.MemoTypeStats + 37, // 11: memos.api.v1.UserStats.tag_count:type_name -> memos.api.v1.UserStats.TagCountEntry 11, // 12: memos.api.v1.ListAllUserStatsResponse.stats:type_name -> memos.api.v1.UserStats - 43, // 13: memos.api.v1.UserSetting.general_setting:type_name -> memos.api.v1.UserSetting.GeneralSetting - 44, // 14: memos.api.v1.UserSetting.sessions_setting:type_name -> memos.api.v1.UserSetting.SessionsSetting - 45, // 15: memos.api.v1.UserSetting.access_tokens_setting:type_name -> memos.api.v1.UserSetting.AccessTokensSetting - 46, // 16: memos.api.v1.UserSetting.webhooks_setting:type_name -> memos.api.v1.UserSetting.WebhooksSetting - 15, // 17: memos.api.v1.UpdateUserSettingRequest.setting:type_name -> memos.api.v1.UserSetting - 50, // 18: memos.api.v1.UpdateUserSettingRequest.update_mask:type_name -> google.protobuf.FieldMask - 15, // 19: memos.api.v1.ListUserSettingsResponse.settings:type_name -> memos.api.v1.UserSetting - 49, // 20: memos.api.v1.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp - 49, // 21: memos.api.v1.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp - 49, // 22: memos.api.v1.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp - 20, // 23: memos.api.v1.ListPersonalAccessTokensResponse.personal_access_tokens:type_name -> memos.api.v1.PersonalAccessToken - 20, // 24: memos.api.v1.CreatePersonalAccessTokenResponse.personal_access_token:type_name -> memos.api.v1.PersonalAccessToken - 49, // 25: memos.api.v1.Session.create_time:type_name -> google.protobuf.Timestamp - 49, // 26: memos.api.v1.Session.last_accessed_time:type_name -> google.protobuf.Timestamp - 47, // 27: memos.api.v1.Session.client_info:type_name -> memos.api.v1.Session.ClientInfo - 26, // 28: memos.api.v1.ListSessionsResponse.sessions:type_name -> memos.api.v1.Session - 49, // 29: memos.api.v1.UserWebhook.create_time:type_name -> google.protobuf.Timestamp - 49, // 30: memos.api.v1.UserWebhook.update_time:type_name -> google.protobuf.Timestamp - 30, // 31: memos.api.v1.ListUserWebhooksResponse.webhooks:type_name -> memos.api.v1.UserWebhook - 30, // 32: memos.api.v1.CreateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook - 30, // 33: memos.api.v1.UpdateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook - 50, // 34: memos.api.v1.UpdateUserWebhookRequest.update_mask:type_name -> google.protobuf.FieldMask - 2, // 35: memos.api.v1.UserNotification.status:type_name -> memos.api.v1.UserNotification.Status - 49, // 36: memos.api.v1.UserNotification.create_time:type_name -> google.protobuf.Timestamp - 3, // 37: memos.api.v1.UserNotification.type:type_name -> memos.api.v1.UserNotification.Type - 36, // 38: memos.api.v1.ListUserNotificationsResponse.notifications:type_name -> memos.api.v1.UserNotification - 36, // 39: memos.api.v1.UpdateUserNotificationRequest.notification:type_name -> memos.api.v1.UserNotification - 50, // 40: memos.api.v1.UpdateUserNotificationRequest.update_mask:type_name -> google.protobuf.FieldMask - 26, // 41: memos.api.v1.UserSetting.SessionsSetting.sessions:type_name -> memos.api.v1.Session - 20, // 42: memos.api.v1.UserSetting.AccessTokensSetting.personal_access_tokens:type_name -> memos.api.v1.PersonalAccessToken - 30, // 43: memos.api.v1.UserSetting.WebhooksSetting.webhooks:type_name -> memos.api.v1.UserWebhook - 5, // 44: memos.api.v1.UserService.ListUsers:input_type -> memos.api.v1.ListUsersRequest - 7, // 45: memos.api.v1.UserService.GetUser:input_type -> memos.api.v1.GetUserRequest - 8, // 46: memos.api.v1.UserService.CreateUser:input_type -> memos.api.v1.CreateUserRequest - 9, // 47: memos.api.v1.UserService.UpdateUser:input_type -> memos.api.v1.UpdateUserRequest - 10, // 48: memos.api.v1.UserService.DeleteUser:input_type -> memos.api.v1.DeleteUserRequest - 13, // 49: memos.api.v1.UserService.ListAllUserStats:input_type -> memos.api.v1.ListAllUserStatsRequest - 12, // 50: memos.api.v1.UserService.GetUserStats:input_type -> memos.api.v1.GetUserStatsRequest - 16, // 51: memos.api.v1.UserService.GetUserSetting:input_type -> memos.api.v1.GetUserSettingRequest - 17, // 52: memos.api.v1.UserService.UpdateUserSetting:input_type -> memos.api.v1.UpdateUserSettingRequest - 18, // 53: memos.api.v1.UserService.ListUserSettings:input_type -> memos.api.v1.ListUserSettingsRequest - 21, // 54: memos.api.v1.UserService.ListPersonalAccessTokens:input_type -> memos.api.v1.ListPersonalAccessTokensRequest - 23, // 55: memos.api.v1.UserService.CreatePersonalAccessToken:input_type -> memos.api.v1.CreatePersonalAccessTokenRequest - 25, // 56: memos.api.v1.UserService.DeletePersonalAccessToken:input_type -> memos.api.v1.DeletePersonalAccessTokenRequest - 27, // 57: memos.api.v1.UserService.ListSessions:input_type -> memos.api.v1.ListSessionsRequest - 29, // 58: memos.api.v1.UserService.RevokeSession:input_type -> memos.api.v1.RevokeSessionRequest - 31, // 59: memos.api.v1.UserService.ListUserWebhooks:input_type -> memos.api.v1.ListUserWebhooksRequest - 33, // 60: memos.api.v1.UserService.CreateUserWebhook:input_type -> memos.api.v1.CreateUserWebhookRequest - 34, // 61: memos.api.v1.UserService.UpdateUserWebhook:input_type -> memos.api.v1.UpdateUserWebhookRequest - 35, // 62: memos.api.v1.UserService.DeleteUserWebhook:input_type -> memos.api.v1.DeleteUserWebhookRequest - 37, // 63: memos.api.v1.UserService.ListUserNotifications:input_type -> memos.api.v1.ListUserNotificationsRequest - 39, // 64: memos.api.v1.UserService.UpdateUserNotification:input_type -> memos.api.v1.UpdateUserNotificationRequest - 40, // 65: memos.api.v1.UserService.DeleteUserNotification:input_type -> memos.api.v1.DeleteUserNotificationRequest - 6, // 66: memos.api.v1.UserService.ListUsers:output_type -> memos.api.v1.ListUsersResponse - 4, // 67: memos.api.v1.UserService.GetUser:output_type -> memos.api.v1.User - 4, // 68: memos.api.v1.UserService.CreateUser:output_type -> memos.api.v1.User - 4, // 69: memos.api.v1.UserService.UpdateUser:output_type -> memos.api.v1.User - 51, // 70: memos.api.v1.UserService.DeleteUser:output_type -> google.protobuf.Empty - 14, // 71: memos.api.v1.UserService.ListAllUserStats:output_type -> memos.api.v1.ListAllUserStatsResponse - 11, // 72: memos.api.v1.UserService.GetUserStats:output_type -> memos.api.v1.UserStats - 15, // 73: memos.api.v1.UserService.GetUserSetting:output_type -> memos.api.v1.UserSetting - 15, // 74: memos.api.v1.UserService.UpdateUserSetting:output_type -> memos.api.v1.UserSetting - 19, // 75: memos.api.v1.UserService.ListUserSettings:output_type -> memos.api.v1.ListUserSettingsResponse - 22, // 76: memos.api.v1.UserService.ListPersonalAccessTokens:output_type -> memos.api.v1.ListPersonalAccessTokensResponse - 24, // 77: memos.api.v1.UserService.CreatePersonalAccessToken:output_type -> memos.api.v1.CreatePersonalAccessTokenResponse - 51, // 78: memos.api.v1.UserService.DeletePersonalAccessToken:output_type -> google.protobuf.Empty - 28, // 79: memos.api.v1.UserService.ListSessions:output_type -> memos.api.v1.ListSessionsResponse - 51, // 80: memos.api.v1.UserService.RevokeSession:output_type -> google.protobuf.Empty - 32, // 81: memos.api.v1.UserService.ListUserWebhooks:output_type -> memos.api.v1.ListUserWebhooksResponse - 30, // 82: memos.api.v1.UserService.CreateUserWebhook:output_type -> memos.api.v1.UserWebhook - 30, // 83: memos.api.v1.UserService.UpdateUserWebhook:output_type -> memos.api.v1.UserWebhook - 51, // 84: memos.api.v1.UserService.DeleteUserWebhook:output_type -> google.protobuf.Empty - 38, // 85: memos.api.v1.UserService.ListUserNotifications:output_type -> memos.api.v1.ListUserNotificationsResponse - 36, // 86: memos.api.v1.UserService.UpdateUserNotification:output_type -> memos.api.v1.UserNotification - 51, // 87: memos.api.v1.UserService.DeleteUserNotification:output_type -> google.protobuf.Empty - 66, // [66:88] is the sub-list for method output_type - 44, // [44:66] is the sub-list for method input_type - 44, // [44:44] is the sub-list for extension type_name - 44, // [44:44] is the sub-list for extension extendee - 0, // [0:44] is the sub-list for field type_name + 39, // 13: memos.api.v1.UserSetting.general_setting:type_name -> memos.api.v1.UserSetting.GeneralSetting + 40, // 14: memos.api.v1.UserSetting.webhooks_setting:type_name -> memos.api.v1.UserSetting.WebhooksSetting + 15, // 15: memos.api.v1.UpdateUserSettingRequest.setting:type_name -> memos.api.v1.UserSetting + 43, // 16: memos.api.v1.UpdateUserSettingRequest.update_mask:type_name -> google.protobuf.FieldMask + 15, // 17: memos.api.v1.ListUserSettingsResponse.settings:type_name -> memos.api.v1.UserSetting + 42, // 18: memos.api.v1.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp + 42, // 19: memos.api.v1.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp + 42, // 20: memos.api.v1.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp + 20, // 21: memos.api.v1.ListPersonalAccessTokensResponse.personal_access_tokens:type_name -> memos.api.v1.PersonalAccessToken + 20, // 22: memos.api.v1.CreatePersonalAccessTokenResponse.personal_access_token:type_name -> memos.api.v1.PersonalAccessToken + 42, // 23: memos.api.v1.UserWebhook.create_time:type_name -> google.protobuf.Timestamp + 42, // 24: memos.api.v1.UserWebhook.update_time:type_name -> google.protobuf.Timestamp + 26, // 25: memos.api.v1.ListUserWebhooksResponse.webhooks:type_name -> memos.api.v1.UserWebhook + 26, // 26: memos.api.v1.CreateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook + 26, // 27: memos.api.v1.UpdateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook + 43, // 28: memos.api.v1.UpdateUserWebhookRequest.update_mask:type_name -> google.protobuf.FieldMask + 2, // 29: memos.api.v1.UserNotification.status:type_name -> memos.api.v1.UserNotification.Status + 42, // 30: memos.api.v1.UserNotification.create_time:type_name -> google.protobuf.Timestamp + 3, // 31: memos.api.v1.UserNotification.type:type_name -> memos.api.v1.UserNotification.Type + 32, // 32: memos.api.v1.ListUserNotificationsResponse.notifications:type_name -> memos.api.v1.UserNotification + 32, // 33: memos.api.v1.UpdateUserNotificationRequest.notification:type_name -> memos.api.v1.UserNotification + 43, // 34: memos.api.v1.UpdateUserNotificationRequest.update_mask:type_name -> google.protobuf.FieldMask + 26, // 35: memos.api.v1.UserSetting.WebhooksSetting.webhooks:type_name -> memos.api.v1.UserWebhook + 5, // 36: memos.api.v1.UserService.ListUsers:input_type -> memos.api.v1.ListUsersRequest + 7, // 37: memos.api.v1.UserService.GetUser:input_type -> memos.api.v1.GetUserRequest + 8, // 38: memos.api.v1.UserService.CreateUser:input_type -> memos.api.v1.CreateUserRequest + 9, // 39: memos.api.v1.UserService.UpdateUser:input_type -> memos.api.v1.UpdateUserRequest + 10, // 40: memos.api.v1.UserService.DeleteUser:input_type -> memos.api.v1.DeleteUserRequest + 13, // 41: memos.api.v1.UserService.ListAllUserStats:input_type -> memos.api.v1.ListAllUserStatsRequest + 12, // 42: memos.api.v1.UserService.GetUserStats:input_type -> memos.api.v1.GetUserStatsRequest + 16, // 43: memos.api.v1.UserService.GetUserSetting:input_type -> memos.api.v1.GetUserSettingRequest + 17, // 44: memos.api.v1.UserService.UpdateUserSetting:input_type -> memos.api.v1.UpdateUserSettingRequest + 18, // 45: memos.api.v1.UserService.ListUserSettings:input_type -> memos.api.v1.ListUserSettingsRequest + 21, // 46: memos.api.v1.UserService.ListPersonalAccessTokens:input_type -> memos.api.v1.ListPersonalAccessTokensRequest + 23, // 47: memos.api.v1.UserService.CreatePersonalAccessToken:input_type -> memos.api.v1.CreatePersonalAccessTokenRequest + 25, // 48: memos.api.v1.UserService.DeletePersonalAccessToken:input_type -> memos.api.v1.DeletePersonalAccessTokenRequest + 27, // 49: memos.api.v1.UserService.ListUserWebhooks:input_type -> memos.api.v1.ListUserWebhooksRequest + 29, // 50: memos.api.v1.UserService.CreateUserWebhook:input_type -> memos.api.v1.CreateUserWebhookRequest + 30, // 51: memos.api.v1.UserService.UpdateUserWebhook:input_type -> memos.api.v1.UpdateUserWebhookRequest + 31, // 52: memos.api.v1.UserService.DeleteUserWebhook:input_type -> memos.api.v1.DeleteUserWebhookRequest + 33, // 53: memos.api.v1.UserService.ListUserNotifications:input_type -> memos.api.v1.ListUserNotificationsRequest + 35, // 54: memos.api.v1.UserService.UpdateUserNotification:input_type -> memos.api.v1.UpdateUserNotificationRequest + 36, // 55: memos.api.v1.UserService.DeleteUserNotification:input_type -> memos.api.v1.DeleteUserNotificationRequest + 6, // 56: memos.api.v1.UserService.ListUsers:output_type -> memos.api.v1.ListUsersResponse + 4, // 57: memos.api.v1.UserService.GetUser:output_type -> memos.api.v1.User + 4, // 58: memos.api.v1.UserService.CreateUser:output_type -> memos.api.v1.User + 4, // 59: memos.api.v1.UserService.UpdateUser:output_type -> memos.api.v1.User + 44, // 60: memos.api.v1.UserService.DeleteUser:output_type -> google.protobuf.Empty + 14, // 61: memos.api.v1.UserService.ListAllUserStats:output_type -> memos.api.v1.ListAllUserStatsResponse + 11, // 62: memos.api.v1.UserService.GetUserStats:output_type -> memos.api.v1.UserStats + 15, // 63: memos.api.v1.UserService.GetUserSetting:output_type -> memos.api.v1.UserSetting + 15, // 64: memos.api.v1.UserService.UpdateUserSetting:output_type -> memos.api.v1.UserSetting + 19, // 65: memos.api.v1.UserService.ListUserSettings:output_type -> memos.api.v1.ListUserSettingsResponse + 22, // 66: memos.api.v1.UserService.ListPersonalAccessTokens:output_type -> memos.api.v1.ListPersonalAccessTokensResponse + 24, // 67: memos.api.v1.UserService.CreatePersonalAccessToken:output_type -> memos.api.v1.CreatePersonalAccessTokenResponse + 44, // 68: memos.api.v1.UserService.DeletePersonalAccessToken:output_type -> google.protobuf.Empty + 28, // 69: memos.api.v1.UserService.ListUserWebhooks:output_type -> memos.api.v1.ListUserWebhooksResponse + 26, // 70: memos.api.v1.UserService.CreateUserWebhook:output_type -> memos.api.v1.UserWebhook + 26, // 71: memos.api.v1.UserService.UpdateUserWebhook:output_type -> memos.api.v1.UserWebhook + 44, // 72: memos.api.v1.UserService.DeleteUserWebhook:output_type -> google.protobuf.Empty + 34, // 73: memos.api.v1.UserService.ListUserNotifications:output_type -> memos.api.v1.ListUserNotificationsResponse + 32, // 74: memos.api.v1.UserService.UpdateUserNotification:output_type -> memos.api.v1.UserNotification + 44, // 75: memos.api.v1.UserService.DeleteUserNotification:output_type -> google.protobuf.Empty + 56, // [56:76] is the sub-list for method output_type + 36, // [36:56] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name } func init() { file_api_v1_user_service_proto_init() } @@ -3382,18 +2891,16 @@ func file_api_v1_user_service_proto_init() { file_api_v1_common_proto_init() file_api_v1_user_service_proto_msgTypes[11].OneofWrappers = []any{ (*UserSetting_GeneralSetting_)(nil), - (*UserSetting_SessionsSetting_)(nil), - (*UserSetting_AccessTokensSetting_)(nil), (*UserSetting_WebhooksSetting_)(nil), } - file_api_v1_user_service_proto_msgTypes[32].OneofWrappers = []any{} + file_api_v1_user_service_proto_msgTypes[28].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_user_service_proto_rawDesc), len(file_api_v1_user_service_proto_rawDesc)), NumEnums: 4, - NumMessages: 44, + NumMessages: 37, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/api/v1/user_service.pb.gw.go b/proto/gen/api/v1/user_service.pb.gw.go index 342077a77..739f22a6b 100644 --- a/proto/gen/api/v1/user_service.pb.gw.go +++ b/proto/gen/api/v1/user_service.pb.gw.go @@ -668,84 +668,6 @@ func local_request_UserService_DeletePersonalAccessToken_0(ctx context.Context, return msg, metadata, err } -func request_UserService_ListSessions_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq ListSessionsRequest - metadata runtime.ServerMetadata - err error - ) - if req.Body != nil { - _, _ = io.Copy(io.Discard, req.Body) - } - val, ok := pathParams["parent"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "parent") - } - protoReq.Parent, err = runtime.String(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err) - } - msg, err := client.ListSessions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err -} - -func local_request_UserService_ListSessions_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq ListSessionsRequest - metadata runtime.ServerMetadata - err error - ) - val, ok := pathParams["parent"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "parent") - } - protoReq.Parent, err = runtime.String(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err) - } - msg, err := server.ListSessions(ctx, &protoReq) - return msg, metadata, err -} - -func request_UserService_RevokeSession_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq RevokeSessionRequest - metadata runtime.ServerMetadata - err error - ) - if req.Body != nil { - _, _ = io.Copy(io.Discard, req.Body) - } - val, ok := pathParams["name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") - } - protoReq.Name, err = runtime.String(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) - } - msg, err := client.RevokeSession(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err -} - -func local_request_UserService_RevokeSession_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq RevokeSessionRequest - metadata runtime.ServerMetadata - err error - ) - val, ok := pathParams["name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") - } - protoReq.Name, err = runtime.String(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) - } - msg, err := server.RevokeSession(ctx, &protoReq) - return msg, metadata, err -} - func request_UserService_ListUserWebhooks_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var ( protoReq ListUserWebhooksRequest @@ -1389,46 +1311,6 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux } forward_UserService_DeletePersonalAccessToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle(http.MethodGet, pattern_UserService_ListSessions_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) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/ListSessions", runtime.WithHTTPPathPattern("/api/v1/{parent=users/*}/sessions")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_UserService_ListSessions_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_ListSessions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) - mux.Handle(http.MethodDelete, pattern_UserService_RevokeSession_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) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/RevokeSession", runtime.WithHTTPPathPattern("/api/v1/{name=users/*/sessions/*}")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_UserService_RevokeSession_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_RevokeSession_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) mux.Handle(http.MethodGet, pattern_UserService_ListUserWebhooks_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1830,40 +1712,6 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux } forward_UserService_DeletePersonalAccessToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle(http.MethodGet, pattern_UserService_ListSessions_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/ListSessions", runtime.WithHTTPPathPattern("/api/v1/{parent=users/*}/sessions")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_UserService_ListSessions_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_ListSessions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) - mux.Handle(http.MethodDelete, pattern_UserService_RevokeSession_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/RevokeSession", runtime.WithHTTPPathPattern("/api/v1/{name=users/*/sessions/*}")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_UserService_RevokeSession_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_RevokeSession_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) mux.Handle(http.MethodGet, pattern_UserService_ListUserWebhooks_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -2000,8 +1848,6 @@ var ( pattern_UserService_ListPersonalAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "personalAccessTokens"}, "")) pattern_UserService_CreatePersonalAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "personalAccessTokens"}, "")) pattern_UserService_DeletePersonalAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "personalAccessTokens", "name"}, "")) - pattern_UserService_ListSessions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "sessions"}, "")) - pattern_UserService_RevokeSession_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "sessions", "name"}, "")) pattern_UserService_ListUserWebhooks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "webhooks"}, "")) pattern_UserService_CreateUserWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "webhooks"}, "")) pattern_UserService_UpdateUserWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "webhooks", "webhook.name"}, "")) @@ -2025,8 +1871,6 @@ var ( forward_UserService_ListPersonalAccessTokens_0 = runtime.ForwardResponseMessage forward_UserService_CreatePersonalAccessToken_0 = runtime.ForwardResponseMessage forward_UserService_DeletePersonalAccessToken_0 = runtime.ForwardResponseMessage - forward_UserService_ListSessions_0 = runtime.ForwardResponseMessage - forward_UserService_RevokeSession_0 = runtime.ForwardResponseMessage forward_UserService_ListUserWebhooks_0 = runtime.ForwardResponseMessage forward_UserService_CreateUserWebhook_0 = runtime.ForwardResponseMessage forward_UserService_UpdateUserWebhook_0 = runtime.ForwardResponseMessage diff --git a/proto/gen/api/v1/user_service_grpc.pb.go b/proto/gen/api/v1/user_service_grpc.pb.go index 90459126f..cef54be93 100644 --- a/proto/gen/api/v1/user_service_grpc.pb.go +++ b/proto/gen/api/v1/user_service_grpc.pb.go @@ -33,8 +33,6 @@ const ( UserService_ListPersonalAccessTokens_FullMethodName = "/memos.api.v1.UserService/ListPersonalAccessTokens" UserService_CreatePersonalAccessToken_FullMethodName = "/memos.api.v1.UserService/CreatePersonalAccessToken" UserService_DeletePersonalAccessToken_FullMethodName = "/memos.api.v1.UserService/DeletePersonalAccessToken" - UserService_ListSessions_FullMethodName = "/memos.api.v1.UserService/ListSessions" - UserService_RevokeSession_FullMethodName = "/memos.api.v1.UserService/RevokeSession" UserService_ListUserWebhooks_FullMethodName = "/memos.api.v1.UserService/ListUserWebhooks" UserService_CreateUserWebhook_FullMethodName = "/memos.api.v1.UserService/CreateUserWebhook" UserService_UpdateUserWebhook_FullMethodName = "/memos.api.v1.UserService/UpdateUserWebhook" @@ -79,13 +77,6 @@ type UserServiceClient interface { CreatePersonalAccessToken(ctx context.Context, in *CreatePersonalAccessTokenRequest, opts ...grpc.CallOption) (*CreatePersonalAccessTokenResponse, error) // DeletePersonalAccessToken deletes a Personal Access Token. DeletePersonalAccessToken(ctx context.Context, in *DeletePersonalAccessTokenRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - // ListSessions returns a list of active login sessions for a user. - // Each session represents a browser/device where the user is logged in. - // Sessions are backed by refresh tokens with sliding expiration. - ListSessions(ctx context.Context, in *ListSessionsRequest, opts ...grpc.CallOption) (*ListSessionsResponse, error) - // RevokeSession revokes a specific login session. - // This invalidates the refresh token, forcing re-authentication on that device. - RevokeSession(ctx context.Context, in *RevokeSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) // ListUserWebhooks returns a list of webhooks for a user. ListUserWebhooks(ctx context.Context, in *ListUserWebhooksRequest, opts ...grpc.CallOption) (*ListUserWebhooksResponse, error) // CreateUserWebhook creates a new webhook for a user. @@ -240,26 +231,6 @@ func (c *userServiceClient) DeletePersonalAccessToken(ctx context.Context, in *D return out, nil } -func (c *userServiceClient) ListSessions(ctx context.Context, in *ListSessionsRequest, opts ...grpc.CallOption) (*ListSessionsResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ListSessionsResponse) - err := c.cc.Invoke(ctx, UserService_ListSessions_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *userServiceClient) RevokeSession(ctx context.Context, in *RevokeSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, UserService_RevokeSession_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *userServiceClient) ListUserWebhooks(ctx context.Context, in *ListUserWebhooksRequest, opts ...grpc.CallOption) (*ListUserWebhooksResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListUserWebhooksResponse) @@ -365,13 +336,6 @@ type UserServiceServer interface { CreatePersonalAccessToken(context.Context, *CreatePersonalAccessTokenRequest) (*CreatePersonalAccessTokenResponse, error) // DeletePersonalAccessToken deletes a Personal Access Token. DeletePersonalAccessToken(context.Context, *DeletePersonalAccessTokenRequest) (*emptypb.Empty, error) - // ListSessions returns a list of active login sessions for a user. - // Each session represents a browser/device where the user is logged in. - // Sessions are backed by refresh tokens with sliding expiration. - ListSessions(context.Context, *ListSessionsRequest) (*ListSessionsResponse, error) - // RevokeSession revokes a specific login session. - // This invalidates the refresh token, forcing re-authentication on that device. - RevokeSession(context.Context, *RevokeSessionRequest) (*emptypb.Empty, error) // ListUserWebhooks returns a list of webhooks for a user. ListUserWebhooks(context.Context, *ListUserWebhooksRequest) (*ListUserWebhooksResponse, error) // CreateUserWebhook creates a new webhook for a user. @@ -435,12 +399,6 @@ func (UnimplementedUserServiceServer) CreatePersonalAccessToken(context.Context, func (UnimplementedUserServiceServer) DeletePersonalAccessToken(context.Context, *DeletePersonalAccessTokenRequest) (*emptypb.Empty, error) { return nil, status.Error(codes.Unimplemented, "method DeletePersonalAccessToken not implemented") } -func (UnimplementedUserServiceServer) ListSessions(context.Context, *ListSessionsRequest) (*ListSessionsResponse, error) { - return nil, status.Error(codes.Unimplemented, "method ListSessions not implemented") -} -func (UnimplementedUserServiceServer) RevokeSession(context.Context, *RevokeSessionRequest) (*emptypb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method RevokeSession not implemented") -} func (UnimplementedUserServiceServer) ListUserWebhooks(context.Context, *ListUserWebhooksRequest) (*ListUserWebhooksResponse, error) { return nil, status.Error(codes.Unimplemented, "method ListUserWebhooks not implemented") } @@ -717,42 +675,6 @@ func _UserService_DeletePersonalAccessToken_Handler(srv interface{}, ctx context return interceptor(ctx, in, info, handler) } -func _UserService_ListSessions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListSessionsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(UserServiceServer).ListSessions(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: UserService_ListSessions_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UserServiceServer).ListSessions(ctx, req.(*ListSessionsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _UserService_RevokeSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RevokeSessionRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(UserServiceServer).RevokeSession(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: UserService_RevokeSession_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UserServiceServer).RevokeSession(ctx, req.(*RevokeSessionRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _UserService_ListUserWebhooks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListUserWebhooksRequest) if err := dec(in); err != nil { @@ -938,14 +860,6 @@ var UserService_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeletePersonalAccessToken", Handler: _UserService_DeletePersonalAccessToken_Handler, }, - { - MethodName: "ListSessions", - Handler: _UserService_ListSessions_Handler, - }, - { - MethodName: "RevokeSession", - Handler: _UserService_RevokeSession_Handler, - }, { MethodName: "ListUserWebhooks", Handler: _UserService_ListUserWebhooks_Handler, diff --git a/proto/gen/openapi.yaml b/proto/gen/openapi.yaml index c83072a03..1e95422e6 100644 --- a/proto/gen/openapi.yaml +++ b/proto/gen/openapi.yaml @@ -1462,66 +1462,6 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' - /api/v1/users/{user}/sessions: - get: - tags: - - UserService - description: |- - ListSessions returns a list of active login sessions for a user. - Each session represents a browser/device where the user is logged in. - Sessions are backed by refresh tokens with sliding expiration. - operationId: UserService_ListSessions - parameters: - - name: user - in: path - description: The user id. - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ListSessionsResponse' - default: - description: Default error response - content: - application/json: - schema: - $ref: '#/components/schemas/Status' - /api/v1/users/{user}/sessions/{session}: - delete: - tags: - - UserService - description: |- - RevokeSession revokes a specific login session. - This invalidates the refresh token, forcing re-authentication on that device. - operationId: UserService_RevokeSession - parameters: - - name: user - in: path - description: The user id. - required: true - schema: - type: string - - name: session - in: path - description: The session id. - required: true - schema: - type: string - responses: - "200": - description: OK - content: {} - default: - description: Default error response - content: - application/json: - schema: - $ref: '#/components/schemas/Status' /api/v1/users/{user}/settings: get: tags: @@ -2431,14 +2371,6 @@ components: type: integer description: The total count of personal access tokens. format: int32 - ListSessionsResponse: - type: object - properties: - sessions: - type: array - items: - $ref: '#/components/schemas/Session' - description: The list of sessions. ListShortcutsResponse: type: object properties: @@ -2750,56 +2682,6 @@ components: type: string description: When the access token expires. format: date-time - Session: - type: object - properties: - name: - type: string - description: |- - The resource name of the session. - Format: users/{user}/sessions/{session} - sessionId: - readOnly: true - type: string - description: The session ID. - createTime: - readOnly: true - type: string - description: The timestamp when the session was created. - format: date-time - lastAccessedTime: - readOnly: true - type: string - description: |- - The timestamp when the session was last accessed. - Used for sliding expiration calculation (last_accessed_time + 2 weeks). - format: date-time - clientInfo: - readOnly: true - allOf: - - $ref: '#/components/schemas/Session_ClientInfo' - description: Client information associated with this session. - description: |- - Session represents a user's login session on a specific device/browser. - Sessions are backed by refresh tokens with sliding expiration. - Session_ClientInfo: - type: object - properties: - userAgent: - type: string - description: User agent string of the client. - ipAddress: - type: string - description: IP address of the client. - deviceType: - type: string - description: Optional. Device type (e.g., "mobile", "desktop", "tablet"). - os: - type: string - description: Optional. Operating system (e.g., "iOS 17.0", "Windows 11"). - browser: - type: string - description: Optional. Browser name and version (e.g., "Chrome 119.0"). SetMemoAttachmentsRequest: required: - name @@ -3071,22 +2953,9 @@ components: For example, "users/123/settings/GENERAL" for general settings. generalSetting: $ref: '#/components/schemas/UserSetting_GeneralSetting' - sessionsSetting: - $ref: '#/components/schemas/UserSetting_SessionsSetting' - accessTokensSetting: - $ref: '#/components/schemas/UserSetting_AccessTokensSetting' webhooksSetting: $ref: '#/components/schemas/UserSetting_WebhooksSetting' description: User settings message - UserSetting_AccessTokensSetting: - type: object - properties: - personalAccessTokens: - type: array - items: - $ref: '#/components/schemas/PersonalAccessToken' - description: List of personal access tokens (PATs). - description: Personal access tokens configuration. UserSetting_GeneralSetting: type: object properties: @@ -3103,15 +2972,6 @@ components: This references a CSS file in the web/public/themes/ directory. If not set, the default theme will be used. description: General user settings configuration. - UserSetting_SessionsSetting: - type: object - properties: - sessions: - type: array - items: - $ref: '#/components/schemas/Session' - description: List of active login sessions. - description: User authentication sessions configuration. UserSetting_WebhooksSetting: type: object properties: diff --git a/proto/gen/store/user_setting.pb.go b/proto/gen/store/user_setting.pb.go index b00b1876b..0a6a33104 100644 --- a/proto/gen/store/user_setting.pb.go +++ b/proto/gen/store/user_setting.pb.go @@ -28,10 +28,6 @@ const ( UserSetting_KEY_UNSPECIFIED UserSetting_Key = 0 // General user settings. UserSetting_GENERAL UserSetting_Key = 1 - // User authentication sessions. - UserSetting_SESSIONS UserSetting_Key = 2 - // Access tokens for the user. - UserSetting_ACCESS_TOKENS UserSetting_Key = 3 // The shortcuts of the user. UserSetting_SHORTCUTS UserSetting_Key = 4 // The webhooks of the user. @@ -47,8 +43,6 @@ var ( UserSetting_Key_name = map[int32]string{ 0: "KEY_UNSPECIFIED", 1: "GENERAL", - 2: "SESSIONS", - 3: "ACCESS_TOKENS", 4: "SHORTCUTS", 5: "WEBHOOKS", 6: "REFRESH_TOKENS", @@ -57,8 +51,6 @@ var ( UserSetting_Key_value = map[string]int32{ "KEY_UNSPECIFIED": 0, "GENERAL": 1, - "SESSIONS": 2, - "ACCESS_TOKENS": 3, "SHORTCUTS": 4, "WEBHOOKS": 5, "REFRESH_TOKENS": 6, @@ -100,8 +92,6 @@ type UserSetting struct { // Types that are valid to be assigned to Value: // // *UserSetting_General - // *UserSetting_Sessions - // *UserSetting_AccessTokens // *UserSetting_Shortcuts // *UserSetting_Webhooks // *UserSetting_RefreshTokens @@ -171,24 +161,6 @@ func (x *UserSetting) GetGeneral() *GeneralUserSetting { return nil } -func (x *UserSetting) GetSessions() *SessionsUserSetting { - if x != nil { - if x, ok := x.Value.(*UserSetting_Sessions); ok { - return x.Sessions - } - } - return nil -} - -func (x *UserSetting) GetAccessTokens() *AccessTokensUserSetting { - if x != nil { - if x, ok := x.Value.(*UserSetting_AccessTokens); ok { - return x.AccessTokens - } - } - return nil -} - func (x *UserSetting) GetShortcuts() *ShortcutsUserSetting { if x != nil { if x, ok := x.Value.(*UserSetting_Shortcuts); ok { @@ -233,14 +205,6 @@ type UserSetting_General struct { General *GeneralUserSetting `protobuf:"bytes,3,opt,name=general,proto3,oneof"` } -type UserSetting_Sessions struct { - Sessions *SessionsUserSetting `protobuf:"bytes,4,opt,name=sessions,proto3,oneof"` -} - -type UserSetting_AccessTokens struct { - AccessTokens *AccessTokensUserSetting `protobuf:"bytes,5,opt,name=access_tokens,json=accessTokens,proto3,oneof"` -} - type UserSetting_Shortcuts struct { Shortcuts *ShortcutsUserSetting `protobuf:"bytes,6,opt,name=shortcuts,proto3,oneof"` } @@ -259,10 +223,6 @@ type UserSetting_PersonalAccessTokens struct { func (*UserSetting_General) isUserSetting_Value() {} -func (*UserSetting_Sessions) isUserSetting_Value() {} - -func (*UserSetting_AccessTokens) isUserSetting_Value() {} - func (*UserSetting_Shortcuts) isUserSetting_Value() {} func (*UserSetting_Webhooks) isUserSetting_Value() {} @@ -335,94 +295,6 @@ func (x *GeneralUserSetting) GetTheme() string { return "" } -type SessionsUserSetting struct { - state protoimpl.MessageState `protogen:"open.v1"` - Sessions []*SessionsUserSetting_Session `protobuf:"bytes,1,rep,name=sessions,proto3" json:"sessions,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SessionsUserSetting) Reset() { - *x = SessionsUserSetting{} - mi := &file_store_user_setting_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SessionsUserSetting) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SessionsUserSetting) ProtoMessage() {} - -func (x *SessionsUserSetting) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SessionsUserSetting.ProtoReflect.Descriptor instead. -func (*SessionsUserSetting) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{2} -} - -func (x *SessionsUserSetting) GetSessions() []*SessionsUserSetting_Session { - if x != nil { - return x.Sessions - } - return nil -} - -type AccessTokensUserSetting struct { - state protoimpl.MessageState `protogen:"open.v1"` - AccessTokens []*AccessTokensUserSetting_AccessToken `protobuf:"bytes,1,rep,name=access_tokens,json=accessTokens,proto3" json:"access_tokens,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AccessTokensUserSetting) Reset() { - *x = AccessTokensUserSetting{} - mi := &file_store_user_setting_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AccessTokensUserSetting) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AccessTokensUserSetting) ProtoMessage() {} - -func (x *AccessTokensUserSetting) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AccessTokensUserSetting.ProtoReflect.Descriptor instead. -func (*AccessTokensUserSetting) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{3} -} - -func (x *AccessTokensUserSetting) GetAccessTokens() []*AccessTokensUserSetting_AccessToken { - if x != nil { - return x.AccessTokens - } - return nil -} - type RefreshTokensUserSetting struct { state protoimpl.MessageState `protogen:"open.v1"` RefreshTokens []*RefreshTokensUserSetting_RefreshToken `protobuf:"bytes,1,rep,name=refresh_tokens,json=refreshTokens,proto3" json:"refresh_tokens,omitempty"` @@ -432,7 +304,7 @@ type RefreshTokensUserSetting struct { func (x *RefreshTokensUserSetting) Reset() { *x = RefreshTokensUserSetting{} - mi := &file_store_user_setting_proto_msgTypes[4] + mi := &file_store_user_setting_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -444,7 +316,7 @@ func (x *RefreshTokensUserSetting) String() string { func (*RefreshTokensUserSetting) ProtoMessage() {} func (x *RefreshTokensUserSetting) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[4] + mi := &file_store_user_setting_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -457,7 +329,7 @@ func (x *RefreshTokensUserSetting) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshTokensUserSetting.ProtoReflect.Descriptor instead. func (*RefreshTokensUserSetting) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{4} + return file_store_user_setting_proto_rawDescGZIP(), []int{2} } func (x *RefreshTokensUserSetting) GetRefreshTokens() []*RefreshTokensUserSetting_RefreshToken { @@ -476,7 +348,7 @@ type PersonalAccessTokensUserSetting struct { func (x *PersonalAccessTokensUserSetting) Reset() { *x = PersonalAccessTokensUserSetting{} - mi := &file_store_user_setting_proto_msgTypes[5] + mi := &file_store_user_setting_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -488,7 +360,7 @@ func (x *PersonalAccessTokensUserSetting) String() string { func (*PersonalAccessTokensUserSetting) ProtoMessage() {} func (x *PersonalAccessTokensUserSetting) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[5] + mi := &file_store_user_setting_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -501,7 +373,7 @@ func (x *PersonalAccessTokensUserSetting) ProtoReflect() protoreflect.Message { // Deprecated: Use PersonalAccessTokensUserSetting.ProtoReflect.Descriptor instead. func (*PersonalAccessTokensUserSetting) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{5} + return file_store_user_setting_proto_rawDescGZIP(), []int{3} } func (x *PersonalAccessTokensUserSetting) GetTokens() []*PersonalAccessTokensUserSetting_PersonalAccessToken { @@ -520,7 +392,7 @@ type ShortcutsUserSetting struct { func (x *ShortcutsUserSetting) Reset() { *x = ShortcutsUserSetting{} - mi := &file_store_user_setting_proto_msgTypes[6] + mi := &file_store_user_setting_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -532,7 +404,7 @@ func (x *ShortcutsUserSetting) String() string { func (*ShortcutsUserSetting) ProtoMessage() {} func (x *ShortcutsUserSetting) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[6] + mi := &file_store_user_setting_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -545,7 +417,7 @@ func (x *ShortcutsUserSetting) ProtoReflect() protoreflect.Message { // Deprecated: Use ShortcutsUserSetting.ProtoReflect.Descriptor instead. func (*ShortcutsUserSetting) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{6} + return file_store_user_setting_proto_rawDescGZIP(), []int{4} } func (x *ShortcutsUserSetting) GetShortcuts() []*ShortcutsUserSetting_Shortcut { @@ -564,7 +436,7 @@ type WebhooksUserSetting struct { func (x *WebhooksUserSetting) Reset() { *x = WebhooksUserSetting{} - mi := &file_store_user_setting_proto_msgTypes[7] + mi := &file_store_user_setting_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -576,7 +448,7 @@ func (x *WebhooksUserSetting) String() string { func (*WebhooksUserSetting) ProtoMessage() {} func (x *WebhooksUserSetting) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[7] + mi := &file_store_user_setting_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -589,7 +461,7 @@ func (x *WebhooksUserSetting) ProtoReflect() protoreflect.Message { // Deprecated: Use WebhooksUserSetting.ProtoReflect.Descriptor instead. func (*WebhooksUserSetting) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{7} + return file_store_user_setting_proto_rawDescGZIP(), []int{5} } func (x *WebhooksUserSetting) GetWebhooks() []*WebhooksUserSetting_Webhook { @@ -599,215 +471,6 @@ func (x *WebhooksUserSetting) GetWebhooks() []*WebhooksUserSetting_Webhook { return nil } -type SessionsUserSetting_Session struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Unique session identifier. - SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` - // Timestamp when the session was created. - CreateTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` - // Timestamp when the session was last accessed. - // Used for sliding expiration calculation (last_accessed_time + 2 weeks). - LastAccessedTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_accessed_time,json=lastAccessedTime,proto3" json:"last_accessed_time,omitempty"` - // Client information associated with this session. - ClientInfo *SessionsUserSetting_ClientInfo `protobuf:"bytes,4,opt,name=client_info,json=clientInfo,proto3" json:"client_info,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SessionsUserSetting_Session) Reset() { - *x = SessionsUserSetting_Session{} - mi := &file_store_user_setting_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SessionsUserSetting_Session) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SessionsUserSetting_Session) ProtoMessage() {} - -func (x *SessionsUserSetting_Session) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[8] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SessionsUserSetting_Session.ProtoReflect.Descriptor instead. -func (*SessionsUserSetting_Session) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{2, 0} -} - -func (x *SessionsUserSetting_Session) GetSessionId() string { - if x != nil { - return x.SessionId - } - return "" -} - -func (x *SessionsUserSetting_Session) GetCreateTime() *timestamppb.Timestamp { - if x != nil { - return x.CreateTime - } - return nil -} - -func (x *SessionsUserSetting_Session) GetLastAccessedTime() *timestamppb.Timestamp { - if x != nil { - return x.LastAccessedTime - } - return nil -} - -func (x *SessionsUserSetting_Session) GetClientInfo() *SessionsUserSetting_ClientInfo { - if x != nil { - return x.ClientInfo - } - return nil -} - -type SessionsUserSetting_ClientInfo struct { - state protoimpl.MessageState `protogen:"open.v1"` - // User agent string of the client. - UserAgent string `protobuf:"bytes,1,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"` - // IP address of the client. - IpAddress string `protobuf:"bytes,2,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - // Optional. Device type (e.g., "mobile", "desktop", "tablet"). - DeviceType string `protobuf:"bytes,3,opt,name=device_type,json=deviceType,proto3" json:"device_type,omitempty"` - // Optional. Operating system (e.g., "iOS 17.0", "Windows 11"). - Os string `protobuf:"bytes,4,opt,name=os,proto3" json:"os,omitempty"` - // Optional. Browser name and version (e.g., "Chrome 119.0"). - Browser string `protobuf:"bytes,5,opt,name=browser,proto3" json:"browser,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SessionsUserSetting_ClientInfo) Reset() { - *x = SessionsUserSetting_ClientInfo{} - mi := &file_store_user_setting_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SessionsUserSetting_ClientInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SessionsUserSetting_ClientInfo) ProtoMessage() {} - -func (x *SessionsUserSetting_ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[9] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SessionsUserSetting_ClientInfo.ProtoReflect.Descriptor instead. -func (*SessionsUserSetting_ClientInfo) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{2, 1} -} - -func (x *SessionsUserSetting_ClientInfo) GetUserAgent() string { - if x != nil { - return x.UserAgent - } - return "" -} - -func (x *SessionsUserSetting_ClientInfo) GetIpAddress() string { - if x != nil { - return x.IpAddress - } - return "" -} - -func (x *SessionsUserSetting_ClientInfo) GetDeviceType() string { - if x != nil { - return x.DeviceType - } - return "" -} - -func (x *SessionsUserSetting_ClientInfo) GetOs() string { - if x != nil { - return x.Os - } - return "" -} - -func (x *SessionsUserSetting_ClientInfo) GetBrowser() string { - if x != nil { - return x.Browser - } - return "" -} - -type AccessTokensUserSetting_AccessToken struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The access token is a JWT token. - // Including expiration time, issuer, etc. - AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` - // A description for the access token. - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AccessTokensUserSetting_AccessToken) Reset() { - *x = AccessTokensUserSetting_AccessToken{} - mi := &file_store_user_setting_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AccessTokensUserSetting_AccessToken) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AccessTokensUserSetting_AccessToken) ProtoMessage() {} - -func (x *AccessTokensUserSetting_AccessToken) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[10] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AccessTokensUserSetting_AccessToken.ProtoReflect.Descriptor instead. -func (*AccessTokensUserSetting_AccessToken) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{3, 0} -} - -func (x *AccessTokensUserSetting_AccessToken) GetAccessToken() string { - if x != nil { - return x.AccessToken - } - return "" -} - -func (x *AccessTokensUserSetting_AccessToken) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - type RefreshTokensUserSetting_RefreshToken struct { state protoimpl.MessageState `protogen:"open.v1"` // Unique identifier (matches 'tid' claim in JWT) @@ -817,7 +480,7 @@ type RefreshTokensUserSetting_RefreshToken struct { // When the token was created CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Client information for session management UI - ClientInfo *SessionsUserSetting_ClientInfo `protobuf:"bytes,4,opt,name=client_info,json=clientInfo,proto3" json:"client_info,omitempty"` + ClientInfo *RefreshTokensUserSetting_ClientInfo `protobuf:"bytes,4,opt,name=client_info,json=clientInfo,proto3" json:"client_info,omitempty"` // Optional description Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` unknownFields protoimpl.UnknownFields @@ -826,7 +489,7 @@ type RefreshTokensUserSetting_RefreshToken struct { func (x *RefreshTokensUserSetting_RefreshToken) Reset() { *x = RefreshTokensUserSetting_RefreshToken{} - mi := &file_store_user_setting_proto_msgTypes[11] + mi := &file_store_user_setting_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -838,7 +501,7 @@ func (x *RefreshTokensUserSetting_RefreshToken) String() string { func (*RefreshTokensUserSetting_RefreshToken) ProtoMessage() {} func (x *RefreshTokensUserSetting_RefreshToken) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[11] + mi := &file_store_user_setting_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -851,7 +514,7 @@ func (x *RefreshTokensUserSetting_RefreshToken) ProtoReflect() protoreflect.Mess // Deprecated: Use RefreshTokensUserSetting_RefreshToken.ProtoReflect.Descriptor instead. func (*RefreshTokensUserSetting_RefreshToken) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{4, 0} + return file_store_user_setting_proto_rawDescGZIP(), []int{2, 0} } func (x *RefreshTokensUserSetting_RefreshToken) GetTokenId() string { @@ -875,7 +538,7 @@ func (x *RefreshTokensUserSetting_RefreshToken) GetCreatedAt() *timestamppb.Time return nil } -func (x *RefreshTokensUserSetting_RefreshToken) GetClientInfo() *SessionsUserSetting_ClientInfo { +func (x *RefreshTokensUserSetting_RefreshToken) GetClientInfo() *RefreshTokensUserSetting_ClientInfo { if x != nil { return x.ClientInfo } @@ -889,6 +552,87 @@ func (x *RefreshTokensUserSetting_RefreshToken) GetDescription() string { return "" } +type RefreshTokensUserSetting_ClientInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + // User agent string of the client. + UserAgent string `protobuf:"bytes,1,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"` + // IP address of the client. + IpAddress string `protobuf:"bytes,2,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + // Optional. Device type (e.g., "mobile", "desktop", "tablet"). + DeviceType string `protobuf:"bytes,3,opt,name=device_type,json=deviceType,proto3" json:"device_type,omitempty"` + // Optional. Operating system (e.g., "iOS 17.0", "Windows 11"). + Os string `protobuf:"bytes,4,opt,name=os,proto3" json:"os,omitempty"` + // Optional. Browser name and version (e.g., "Chrome 119.0"). + Browser string `protobuf:"bytes,5,opt,name=browser,proto3" json:"browser,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RefreshTokensUserSetting_ClientInfo) Reset() { + *x = RefreshTokensUserSetting_ClientInfo{} + mi := &file_store_user_setting_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RefreshTokensUserSetting_ClientInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshTokensUserSetting_ClientInfo) ProtoMessage() {} + +func (x *RefreshTokensUserSetting_ClientInfo) ProtoReflect() protoreflect.Message { + mi := &file_store_user_setting_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshTokensUserSetting_ClientInfo.ProtoReflect.Descriptor instead. +func (*RefreshTokensUserSetting_ClientInfo) Descriptor() ([]byte, []int) { + return file_store_user_setting_proto_rawDescGZIP(), []int{2, 1} +} + +func (x *RefreshTokensUserSetting_ClientInfo) GetUserAgent() string { + if x != nil { + return x.UserAgent + } + return "" +} + +func (x *RefreshTokensUserSetting_ClientInfo) GetIpAddress() string { + if x != nil { + return x.IpAddress + } + return "" +} + +func (x *RefreshTokensUserSetting_ClientInfo) GetDeviceType() string { + if x != nil { + return x.DeviceType + } + return "" +} + +func (x *RefreshTokensUserSetting_ClientInfo) GetOs() string { + if x != nil { + return x.Os + } + return "" +} + +func (x *RefreshTokensUserSetting_ClientInfo) GetBrowser() string { + if x != nil { + return x.Browser + } + return "" +} + type PersonalAccessTokensUserSetting_PersonalAccessToken struct { state protoimpl.MessageState `protogen:"open.v1"` // Unique identifier for this token @@ -909,7 +653,7 @@ type PersonalAccessTokensUserSetting_PersonalAccessToken struct { func (x *PersonalAccessTokensUserSetting_PersonalAccessToken) Reset() { *x = PersonalAccessTokensUserSetting_PersonalAccessToken{} - mi := &file_store_user_setting_proto_msgTypes[12] + mi := &file_store_user_setting_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -921,7 +665,7 @@ func (x *PersonalAccessTokensUserSetting_PersonalAccessToken) String() string { func (*PersonalAccessTokensUserSetting_PersonalAccessToken) ProtoMessage() {} func (x *PersonalAccessTokensUserSetting_PersonalAccessToken) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[12] + mi := &file_store_user_setting_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -934,7 +678,7 @@ func (x *PersonalAccessTokensUserSetting_PersonalAccessToken) ProtoReflect() pro // Deprecated: Use PersonalAccessTokensUserSetting_PersonalAccessToken.ProtoReflect.Descriptor instead. func (*PersonalAccessTokensUserSetting_PersonalAccessToken) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{5, 0} + return file_store_user_setting_proto_rawDescGZIP(), []int{3, 0} } func (x *PersonalAccessTokensUserSetting_PersonalAccessToken) GetTokenId() string { @@ -990,7 +734,7 @@ type ShortcutsUserSetting_Shortcut struct { func (x *ShortcutsUserSetting_Shortcut) Reset() { *x = ShortcutsUserSetting_Shortcut{} - mi := &file_store_user_setting_proto_msgTypes[13] + mi := &file_store_user_setting_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1002,7 +746,7 @@ func (x *ShortcutsUserSetting_Shortcut) String() string { func (*ShortcutsUserSetting_Shortcut) ProtoMessage() {} func (x *ShortcutsUserSetting_Shortcut) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[13] + mi := &file_store_user_setting_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1015,7 +759,7 @@ func (x *ShortcutsUserSetting_Shortcut) ProtoReflect() protoreflect.Message { // Deprecated: Use ShortcutsUserSetting_Shortcut.ProtoReflect.Descriptor instead. func (*ShortcutsUserSetting_Shortcut) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{6, 0} + return file_store_user_setting_proto_rawDescGZIP(), []int{4, 0} } func (x *ShortcutsUserSetting_Shortcut) GetId() string { @@ -1053,7 +797,7 @@ type WebhooksUserSetting_Webhook struct { func (x *WebhooksUserSetting_Webhook) Reset() { *x = WebhooksUserSetting_Webhook{} - mi := &file_store_user_setting_proto_msgTypes[14] + mi := &file_store_user_setting_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1065,7 +809,7 @@ func (x *WebhooksUserSetting_Webhook) String() string { func (*WebhooksUserSetting_Webhook) ProtoMessage() {} func (x *WebhooksUserSetting_Webhook) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[14] + mi := &file_store_user_setting_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1078,7 +822,7 @@ func (x *WebhooksUserSetting_Webhook) ProtoReflect() protoreflect.Message { // Deprecated: Use WebhooksUserSetting_Webhook.ProtoReflect.Descriptor instead. func (*WebhooksUserSetting_Webhook) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{7, 0} + return file_store_user_setting_proto_rawDescGZIP(), []int{5, 0} } func (x *WebhooksUserSetting_Webhook) GetId() string { @@ -1106,22 +850,18 @@ var File_store_user_setting_proto protoreflect.FileDescriptor const file_store_user_setting_proto_rawDesc = "" + "\n" + - "\x18store/user_setting.proto\x12\vmemos.store\x1a\x1fgoogle/protobuf/timestamp.proto\"\xfa\x05\n" + + "\x18store/user_setting.proto\x12\vmemos.store\x1a\x1fgoogle/protobuf/timestamp.proto\"\xcb\x04\n" + "\vUserSetting\x12\x17\n" + "\auser_id\x18\x01 \x01(\x05R\x06userId\x12.\n" + "\x03key\x18\x02 \x01(\x0e2\x1c.memos.store.UserSetting.KeyR\x03key\x12;\n" + - "\ageneral\x18\x03 \x01(\v2\x1f.memos.store.GeneralUserSettingH\x00R\ageneral\x12>\n" + - "\bsessions\x18\x04 \x01(\v2 .memos.store.SessionsUserSettingH\x00R\bsessions\x12K\n" + - "\raccess_tokens\x18\x05 \x01(\v2$.memos.store.AccessTokensUserSettingH\x00R\faccessTokens\x12A\n" + + "\ageneral\x18\x03 \x01(\v2\x1f.memos.store.GeneralUserSettingH\x00R\ageneral\x12A\n" + "\tshortcuts\x18\x06 \x01(\v2!.memos.store.ShortcutsUserSettingH\x00R\tshortcuts\x12>\n" + "\bwebhooks\x18\a \x01(\v2 .memos.store.WebhooksUserSettingH\x00R\bwebhooks\x12N\n" + "\x0erefresh_tokens\x18\b \x01(\v2%.memos.store.RefreshTokensUserSettingH\x00R\rrefreshTokens\x12d\n" + - "\x16personal_access_tokens\x18\t \x01(\v2,.memos.store.PersonalAccessTokensUserSettingH\x00R\x14personalAccessTokens\"\x95\x01\n" + + "\x16personal_access_tokens\x18\t \x01(\v2,.memos.store.PersonalAccessTokensUserSettingH\x00R\x14personalAccessTokens\"t\n" + "\x03Key\x12\x13\n" + "\x0fKEY_UNSPECIFIED\x10\x00\x12\v\n" + - "\aGENERAL\x10\x01\x12\f\n" + - "\bSESSIONS\x10\x02\x12\x11\n" + - "\rACCESS_TOKENS\x10\x03\x12\r\n" + + "\aGENERAL\x10\x01\x12\r\n" + "\tSHORTCUTS\x10\x04\x12\f\n" + "\bWEBHOOKS\x10\x05\x12\x12\n" + "\x0eREFRESH_TOKENS\x10\x06\x12\x1a\n" + @@ -1130,17 +870,18 @@ const file_store_user_setting_proto_rawDesc = "" + "\x12GeneralUserSetting\x12\x16\n" + "\x06locale\x18\x01 \x01(\tR\x06locale\x12'\n" + "\x0fmemo_visibility\x18\x02 \x01(\tR\x0ememoVisibility\x12\x14\n" + - "\x05theme\x18\x03 \x01(\tR\x05theme\"\xf3\x03\n" + - "\x13SessionsUserSetting\x12D\n" + - "\bsessions\x18\x01 \x03(\v2(.memos.store.SessionsUserSetting.SessionR\bsessions\x1a\xfd\x01\n" + - "\aSession\x12\x1d\n" + + "\x05theme\x18\x03 \x01(\tR\x05theme\"\xa4\x04\n" + + "\x18RefreshTokensUserSetting\x12Y\n" + + "\x0erefresh_tokens\x18\x01 \x03(\v22.memos.store.RefreshTokensUserSetting.RefreshTokenR\rrefreshTokens\x1a\x94\x02\n" + + "\fRefreshToken\x12\x19\n" + + "\btoken_id\x18\x01 \x01(\tR\atokenId\x129\n" + "\n" + - "session_id\x18\x01 \x01(\tR\tsessionId\x12;\n" + - "\vcreate_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "createTime\x12H\n" + - "\x12last_accessed_time\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x10lastAccessedTime\x12L\n" + - "\vclient_info\x18\x04 \x01(\v2+.memos.store.SessionsUserSetting.ClientInfoR\n" + - "clientInfo\x1a\x95\x01\n" + + "expires_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x129\n" + + "\n" + + "created_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12Q\n" + + "\vclient_info\x18\x04 \x01(\v20.memos.store.RefreshTokensUserSetting.ClientInfoR\n" + + "clientInfo\x12 \n" + + "\vdescription\x18\x05 \x01(\tR\vdescription\x1a\x95\x01\n" + "\n" + "ClientInfo\x12\x1d\n" + "\n" + @@ -1150,23 +891,7 @@ const file_store_user_setting_proto_rawDesc = "" + "\vdevice_type\x18\x03 \x01(\tR\n" + "deviceType\x12\x0e\n" + "\x02os\x18\x04 \x01(\tR\x02os\x12\x18\n" + - "\abrowser\x18\x05 \x01(\tR\abrowser\"\xc4\x01\n" + - "\x17AccessTokensUserSetting\x12U\n" + - "\raccess_tokens\x18\x01 \x03(\v20.memos.store.AccessTokensUserSetting.AccessTokenR\faccessTokens\x1aR\n" + - "\vAccessToken\x12!\n" + - "\faccess_token\x18\x01 \x01(\tR\vaccessToken\x12 \n" + - "\vdescription\x18\x02 \x01(\tR\vdescription\"\x87\x03\n" + - "\x18RefreshTokensUserSetting\x12Y\n" + - "\x0erefresh_tokens\x18\x01 \x03(\v22.memos.store.RefreshTokensUserSetting.RefreshTokenR\rrefreshTokens\x1a\x8f\x02\n" + - "\fRefreshToken\x12\x19\n" + - "\btoken_id\x18\x01 \x01(\tR\atokenId\x129\n" + - "\n" + - "expires_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x129\n" + - "\n" + - "created_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12L\n" + - "\vclient_info\x18\x04 \x01(\v2+.memos.store.SessionsUserSetting.ClientInfoR\n" + - "clientInfo\x12 \n" + - "\vdescription\x18\x05 \x01(\tR\vdescription\"\xa3\x03\n" + + "\abrowser\x18\x05 \x01(\tR\abrowser\"\xa3\x03\n" + "\x1fPersonalAccessTokensUserSetting\x12X\n" + "\x06tokens\x18\x01 \x03(\v2@.memos.store.PersonalAccessTokensUserSetting.PersonalAccessTokenR\x06tokens\x1a\xa5\x02\n" + "\x13PersonalAccessToken\x12\x19\n" + @@ -1207,55 +932,44 @@ func file_store_user_setting_proto_rawDescGZIP() []byte { } var file_store_user_setting_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_store_user_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_store_user_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_store_user_setting_proto_goTypes = []any{ (UserSetting_Key)(0), // 0: memos.store.UserSetting.Key (*UserSetting)(nil), // 1: memos.store.UserSetting (*GeneralUserSetting)(nil), // 2: memos.store.GeneralUserSetting - (*SessionsUserSetting)(nil), // 3: memos.store.SessionsUserSetting - (*AccessTokensUserSetting)(nil), // 4: memos.store.AccessTokensUserSetting - (*RefreshTokensUserSetting)(nil), // 5: memos.store.RefreshTokensUserSetting - (*PersonalAccessTokensUserSetting)(nil), // 6: memos.store.PersonalAccessTokensUserSetting - (*ShortcutsUserSetting)(nil), // 7: memos.store.ShortcutsUserSetting - (*WebhooksUserSetting)(nil), // 8: memos.store.WebhooksUserSetting - (*SessionsUserSetting_Session)(nil), // 9: memos.store.SessionsUserSetting.Session - (*SessionsUserSetting_ClientInfo)(nil), // 10: memos.store.SessionsUserSetting.ClientInfo - (*AccessTokensUserSetting_AccessToken)(nil), // 11: memos.store.AccessTokensUserSetting.AccessToken - (*RefreshTokensUserSetting_RefreshToken)(nil), // 12: memos.store.RefreshTokensUserSetting.RefreshToken - (*PersonalAccessTokensUserSetting_PersonalAccessToken)(nil), // 13: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken - (*ShortcutsUserSetting_Shortcut)(nil), // 14: memos.store.ShortcutsUserSetting.Shortcut - (*WebhooksUserSetting_Webhook)(nil), // 15: memos.store.WebhooksUserSetting.Webhook - (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp + (*RefreshTokensUserSetting)(nil), // 3: memos.store.RefreshTokensUserSetting + (*PersonalAccessTokensUserSetting)(nil), // 4: memos.store.PersonalAccessTokensUserSetting + (*ShortcutsUserSetting)(nil), // 5: memos.store.ShortcutsUserSetting + (*WebhooksUserSetting)(nil), // 6: memos.store.WebhooksUserSetting + (*RefreshTokensUserSetting_RefreshToken)(nil), // 7: memos.store.RefreshTokensUserSetting.RefreshToken + (*RefreshTokensUserSetting_ClientInfo)(nil), // 8: memos.store.RefreshTokensUserSetting.ClientInfo + (*PersonalAccessTokensUserSetting_PersonalAccessToken)(nil), // 9: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken + (*ShortcutsUserSetting_Shortcut)(nil), // 10: memos.store.ShortcutsUserSetting.Shortcut + (*WebhooksUserSetting_Webhook)(nil), // 11: memos.store.WebhooksUserSetting.Webhook + (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp } var file_store_user_setting_proto_depIdxs = []int32{ 0, // 0: memos.store.UserSetting.key:type_name -> memos.store.UserSetting.Key 2, // 1: memos.store.UserSetting.general:type_name -> memos.store.GeneralUserSetting - 3, // 2: memos.store.UserSetting.sessions:type_name -> memos.store.SessionsUserSetting - 4, // 3: memos.store.UserSetting.access_tokens:type_name -> memos.store.AccessTokensUserSetting - 7, // 4: memos.store.UserSetting.shortcuts:type_name -> memos.store.ShortcutsUserSetting - 8, // 5: memos.store.UserSetting.webhooks:type_name -> memos.store.WebhooksUserSetting - 5, // 6: memos.store.UserSetting.refresh_tokens:type_name -> memos.store.RefreshTokensUserSetting - 6, // 7: memos.store.UserSetting.personal_access_tokens:type_name -> memos.store.PersonalAccessTokensUserSetting - 9, // 8: memos.store.SessionsUserSetting.sessions:type_name -> memos.store.SessionsUserSetting.Session - 11, // 9: memos.store.AccessTokensUserSetting.access_tokens:type_name -> memos.store.AccessTokensUserSetting.AccessToken - 12, // 10: memos.store.RefreshTokensUserSetting.refresh_tokens:type_name -> memos.store.RefreshTokensUserSetting.RefreshToken - 13, // 11: memos.store.PersonalAccessTokensUserSetting.tokens:type_name -> memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken - 14, // 12: memos.store.ShortcutsUserSetting.shortcuts:type_name -> memos.store.ShortcutsUserSetting.Shortcut - 15, // 13: memos.store.WebhooksUserSetting.webhooks:type_name -> memos.store.WebhooksUserSetting.Webhook - 16, // 14: memos.store.SessionsUserSetting.Session.create_time:type_name -> google.protobuf.Timestamp - 16, // 15: memos.store.SessionsUserSetting.Session.last_accessed_time:type_name -> google.protobuf.Timestamp - 10, // 16: memos.store.SessionsUserSetting.Session.client_info:type_name -> memos.store.SessionsUserSetting.ClientInfo - 16, // 17: memos.store.RefreshTokensUserSetting.RefreshToken.expires_at:type_name -> google.protobuf.Timestamp - 16, // 18: memos.store.RefreshTokensUserSetting.RefreshToken.created_at:type_name -> google.protobuf.Timestamp - 10, // 19: memos.store.RefreshTokensUserSetting.RefreshToken.client_info:type_name -> memos.store.SessionsUserSetting.ClientInfo - 16, // 20: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp - 16, // 21: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp - 16, // 22: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp - 23, // [23:23] is the sub-list for method output_type - 23, // [23:23] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name + 5, // 2: memos.store.UserSetting.shortcuts:type_name -> memos.store.ShortcutsUserSetting + 6, // 3: memos.store.UserSetting.webhooks:type_name -> memos.store.WebhooksUserSetting + 3, // 4: memos.store.UserSetting.refresh_tokens:type_name -> memos.store.RefreshTokensUserSetting + 4, // 5: memos.store.UserSetting.personal_access_tokens:type_name -> memos.store.PersonalAccessTokensUserSetting + 7, // 6: memos.store.RefreshTokensUserSetting.refresh_tokens:type_name -> memos.store.RefreshTokensUserSetting.RefreshToken + 9, // 7: memos.store.PersonalAccessTokensUserSetting.tokens:type_name -> memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken + 10, // 8: memos.store.ShortcutsUserSetting.shortcuts:type_name -> memos.store.ShortcutsUserSetting.Shortcut + 11, // 9: memos.store.WebhooksUserSetting.webhooks:type_name -> memos.store.WebhooksUserSetting.Webhook + 12, // 10: memos.store.RefreshTokensUserSetting.RefreshToken.expires_at:type_name -> google.protobuf.Timestamp + 12, // 11: memos.store.RefreshTokensUserSetting.RefreshToken.created_at:type_name -> google.protobuf.Timestamp + 8, // 12: memos.store.RefreshTokensUserSetting.RefreshToken.client_info:type_name -> memos.store.RefreshTokensUserSetting.ClientInfo + 12, // 13: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp + 12, // 14: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp + 12, // 15: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_store_user_setting_proto_init() } @@ -1265,8 +979,6 @@ func file_store_user_setting_proto_init() { } file_store_user_setting_proto_msgTypes[0].OneofWrappers = []any{ (*UserSetting_General)(nil), - (*UserSetting_Sessions)(nil), - (*UserSetting_AccessTokens)(nil), (*UserSetting_Shortcuts)(nil), (*UserSetting_Webhooks)(nil), (*UserSetting_RefreshTokens)(nil), @@ -1278,7 +990,7 @@ func file_store_user_setting_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_store_user_setting_proto_rawDesc), len(file_store_user_setting_proto_rawDesc)), NumEnums: 1, - NumMessages: 15, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/store/user_setting.proto b/proto/store/user_setting.proto index f3fc1eab9..6a065e609 100644 --- a/proto/store/user_setting.proto +++ b/proto/store/user_setting.proto @@ -11,10 +11,6 @@ message UserSetting { KEY_UNSPECIFIED = 0; // General user settings. GENERAL = 1; - // User authentication sessions. - SESSIONS = 2; - // Access tokens for the user. - ACCESS_TOKENS = 3; // The shortcuts of the user. SHORTCUTS = 4; // The webhooks of the user. @@ -30,8 +26,6 @@ message UserSetting { Key key = 2; oneof value { GeneralUserSetting general = 3; - SessionsUserSetting sessions = 4; - AccessTokensUserSetting access_tokens = 5; ShortcutsUserSetting shortcuts = 6; WebhooksUserSetting webhooks = 7; RefreshTokensUserSetting refresh_tokens = 8; @@ -49,17 +43,18 @@ message GeneralUserSetting { string theme = 3; } -message SessionsUserSetting { - message Session { - // Unique session identifier. - string session_id = 1; - // Timestamp when the session was created. - google.protobuf.Timestamp create_time = 2; - // Timestamp when the session was last accessed. - // Used for sliding expiration calculation (last_accessed_time + 2 weeks). - google.protobuf.Timestamp last_accessed_time = 3; - // Client information associated with this session. +message RefreshTokensUserSetting { + message RefreshToken { + // Unique identifier (matches 'tid' claim in JWT) + string token_id = 1; + // When the token expires + google.protobuf.Timestamp expires_at = 2; + // When the token was created + google.protobuf.Timestamp created_at = 3; + // Client information for session management UI ClientInfo client_info = 4; + // Optional description + string description = 5; } message ClientInfo { @@ -75,33 +70,6 @@ message SessionsUserSetting { string browser = 5; } - repeated Session sessions = 1; -} - -message AccessTokensUserSetting { - message AccessToken { - // The access token is a JWT token. - // Including expiration time, issuer, etc. - string access_token = 1; - // A description for the access token. - string description = 2; - } - repeated AccessToken access_tokens = 1; -} - -message RefreshTokensUserSetting { - message RefreshToken { - // Unique identifier (matches 'tid' claim in JWT) - string token_id = 1; - // When the token expires - google.protobuf.Timestamp expires_at = 2; - // When the token was created - google.protobuf.Timestamp created_at = 3; - // Client information for session management UI - SessionsUserSetting.ClientInfo client_info = 4; - // Optional description - string description = 5; - } repeated RefreshToken refresh_tokens = 1; } diff --git a/server/router/api/v1/auth_service.go b/server/router/api/v1/auth_service.go index 1e60f421a..4ec3d4084 100644 --- a/server/router/api/v1/auth_service.go +++ b/server/router/api/v1/auth_service.go @@ -394,8 +394,8 @@ func (s *APIV1Service) fetchCurrentUser(ctx context.Context) (*store.User, error // - See all active sessions with device details // - Identify suspicious login attempts // - Revoke specific sessions from unknown devices. -func (s *APIV1Service) extractClientInfo(ctx context.Context) *storepb.SessionsUserSetting_ClientInfo { - clientInfo := &storepb.SessionsUserSetting_ClientInfo{} +func (s *APIV1Service) extractClientInfo(ctx context.Context) *storepb.RefreshTokensUserSetting_ClientInfo { + clientInfo := &storepb.RefreshTokensUserSetting_ClientInfo{} // Extract user agent from metadata if available if md, ok := metadata.FromIncomingContext(ctx); ok { @@ -427,7 +427,7 @@ func (s *APIV1Service) extractClientInfo(ctx context.Context) *storepb.SessionsU // // Note: This is a simplified parser. For production use with high accuracy requirements, // consider using a dedicated user agent parsing library. -func (*APIV1Service) parseUserAgent(userAgent string, clientInfo *storepb.SessionsUserSetting_ClientInfo) { +func (*APIV1Service) parseUserAgent(userAgent string, clientInfo *storepb.RefreshTokensUserSetting_ClientInfo) { if userAgent == "" { return } diff --git a/server/router/api/v1/auth_service_client_info_test.go b/server/router/api/v1/auth_service_client_info_test.go index 4d87764e6..300663c04 100644 --- a/server/router/api/v1/auth_service_client_info_test.go +++ b/server/router/api/v1/auth_service_client_info_test.go @@ -72,7 +72,7 @@ func TestParseUserAgent(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - clientInfo := &storepb.SessionsUserSetting_ClientInfo{} + clientInfo := &storepb.RefreshTokensUserSetting_ClientInfo{} service.parseUserAgent(tt.userAgent, clientInfo) if clientInfo.DeviceType != tt.expectedDevice { @@ -155,7 +155,7 @@ func TestClientInfoExamples(t *testing.T) { for _, example := range examples { t.Run(example.description, func(t *testing.T) { - clientInfo := &storepb.SessionsUserSetting_ClientInfo{} + clientInfo := &storepb.RefreshTokensUserSetting_ClientInfo{} service.parseUserAgent(example.userAgent, clientInfo) t.Logf("User Agent: %s", example.userAgent) diff --git a/server/router/api/v1/connect_services.go b/server/router/api/v1/connect_services.go index 9ac7af796..d8124d8aa 100644 --- a/server/router/api/v1/connect_services.go +++ b/server/router/api/v1/connect_services.go @@ -175,22 +175,6 @@ func (s *ConnectServiceHandler) DeletePersonalAccessToken(ctx context.Context, r return connect.NewResponse(resp), nil } -func (s *ConnectServiceHandler) ListSessions(ctx context.Context, req *connect.Request[v1pb.ListSessionsRequest]) (*connect.Response[v1pb.ListSessionsResponse], error) { - resp, err := s.APIV1Service.ListSessions(ctx, req.Msg) - if err != nil { - return nil, convertGRPCError(err) - } - return connect.NewResponse(resp), nil -} - -func (s *ConnectServiceHandler) RevokeSession(ctx context.Context, req *connect.Request[v1pb.RevokeSessionRequest]) (*connect.Response[emptypb.Empty], error) { - resp, err := s.APIV1Service.RevokeSession(ctx, req.Msg) - if err != nil { - return nil, convertGRPCError(err) - } - return connect.NewResponse(resp), nil -} - func (s *ConnectServiceHandler) ListUserWebhooks(ctx context.Context, req *connect.Request[v1pb.ListUserWebhooksRequest]) (*connect.Response[v1pb.ListUserWebhooksResponse], error) { resp, err := s.APIV1Service.ListUserWebhooks(ctx, req.Msg) if err != nil { diff --git a/server/router/api/v1/user_service.go b/server/router/api/v1/user_service.go index a33b98d56..e5fcbfd07 100644 --- a/server/router/api/v1/user_service.go +++ b/server/router/api/v1/user_service.go @@ -655,82 +655,6 @@ func (s *APIV1Service) DeletePersonalAccessToken(ctx context.Context, request *v return &emptypb.Empty{}, nil } -// ListSessions returns all active login sessions for a user. -// Each session represents a device/browser where the user is logged in, -// backed by refresh tokens with sliding expiration. -func (s *APIV1Service) ListSessions(ctx context.Context, request *v1pb.ListSessionsRequest) (*v1pb.ListSessionsResponse, error) { - userID, err := ExtractUserIDFromName(request.Parent) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err) - } - - // Verify permission. - claims := auth.GetUserClaims(ctx) - if claims == nil || claims.UserID != userID { - currentUser, _ := s.fetchCurrentUser(ctx) - if currentUser == nil || (currentUser.ID != userID && currentUser.Role != store.RoleHost && currentUser.Role != store.RoleAdmin) { - return nil, status.Errorf(codes.PermissionDenied, "permission denied") - } - } - - refreshTokens, err := s.Store.GetUserRefreshTokens(ctx, userID) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get sessions: %v", err) - } - - sessions := make([]*v1pb.Session, 0, len(refreshTokens)) - for _, token := range refreshTokens { - session := &v1pb.Session{ - Name: fmt.Sprintf("%s/sessions/%s", request.Parent, token.TokenId), - SessionId: token.TokenId, - CreateTime: token.CreatedAt, - } - if token.ClientInfo != nil { - session.ClientInfo = &v1pb.Session_ClientInfo{ - UserAgent: token.ClientInfo.UserAgent, - IpAddress: token.ClientInfo.IpAddress, - DeviceType: token.ClientInfo.DeviceType, - Os: token.ClientInfo.Os, - Browser: token.ClientInfo.Browser, - } - } - sessions = append(sessions, session) - } - - return &v1pb.ListSessionsResponse{Sessions: sessions}, nil -} - -// RevokeSession revokes a specific login session. -// This invalidates the refresh token, forcing re-authentication on that device. -func (s *APIV1Service) RevokeSession(ctx context.Context, request *v1pb.RevokeSessionRequest) (*emptypb.Empty, error) { - // Parse name: users/{user_id}/sessions/{session_id} - parts := strings.Split(request.Name, "/") - if len(parts) != 4 || parts[0] != "users" || parts[2] != "sessions" { - return nil, status.Errorf(codes.InvalidArgument, "invalid session name") - } - - userID, err := util.ConvertStringToInt32(parts[1]) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "invalid user ID: %v", err) - } - sessionID := parts[3] - - // Verify permission. - claims := auth.GetUserClaims(ctx) - if claims == nil || claims.UserID != userID { - currentUser, _ := s.fetchCurrentUser(ctx) - if currentUser == nil || (currentUser.ID != userID && currentUser.Role != store.RoleHost && currentUser.Role != store.RoleAdmin) { - return nil, status.Errorf(codes.PermissionDenied, "permission denied") - } - } - - if err := s.Store.RemoveUserRefreshToken(ctx, userID, sessionID); err != nil { - return nil, status.Errorf(codes.Internal, "failed to revoke session: %v", err) - } - - return &emptypb.Empty{}, nil -} - func (s *APIV1Service) ListUserWebhooks(ctx context.Context, request *v1pb.ListUserWebhooksRequest) (*v1pb.ListUserWebhooksResponse, error) { userID, err := ExtractUserIDFromName(request.Parent) if err != nil { diff --git a/store/user_setting.go b/store/user_setting.go index 619a3b2ec..40a1c0480 100644 --- a/store/user_setting.go +++ b/store/user_setting.go @@ -401,18 +401,6 @@ func convertUserSettingFromRaw(raw *UserSetting) (*storepb.UserSetting, error) { } switch raw.Key { - case storepb.UserSetting_ACCESS_TOKENS: - accessTokensUserSetting := &storepb.AccessTokensUserSetting{} - if err := protojsonUnmarshaler.Unmarshal([]byte(raw.Value), accessTokensUserSetting); err != nil { - return nil, err - } - userSetting.Value = &storepb.UserSetting_AccessTokens{AccessTokens: accessTokensUserSetting} - case storepb.UserSetting_SESSIONS: - sessionsUserSetting := &storepb.SessionsUserSetting{} - if err := protojsonUnmarshaler.Unmarshal([]byte(raw.Value), sessionsUserSetting); err != nil { - return nil, err - } - userSetting.Value = &storepb.UserSetting_Sessions{Sessions: sessionsUserSetting} case storepb.UserSetting_SHORTCUTS: shortcutsUserSetting := &storepb.ShortcutsUserSetting{} if err := protojsonUnmarshaler.Unmarshal([]byte(raw.Value), shortcutsUserSetting); err != nil { @@ -456,20 +444,6 @@ func convertUserSettingToRaw(userSetting *storepb.UserSetting) (*UserSetting, er } switch userSetting.Key { - case storepb.UserSetting_ACCESS_TOKENS: - accessTokensUserSetting := userSetting.GetAccessTokens() - value, err := protojson.Marshal(accessTokensUserSetting) - if err != nil { - return nil, err - } - raw.Value = string(value) - case storepb.UserSetting_SESSIONS: - sessionsUserSetting := userSetting.GetSessions() - value, err := protojson.Marshal(sessionsUserSetting) - if err != nil { - return nil, err - } - raw.Value = string(value) case storepb.UserSetting_SHORTCUTS: shortcutsUserSetting := userSetting.GetShortcuts() value, err := protojson.Marshal(shortcutsUserSetting) diff --git a/web/src/components/Settings/MyAccountSection.tsx b/web/src/components/Settings/MyAccountSection.tsx index 3bd7add0b..39331a2c7 100644 --- a/web/src/components/Settings/MyAccountSection.tsx +++ b/web/src/components/Settings/MyAccountSection.tsx @@ -10,7 +10,6 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigge import AccessTokenSection from "./AccessTokenSection"; import SettingGroup from "./SettingGroup"; import SettingSection from "./SettingSection"; -import UserSessionsSection from "./UserSessionsSection"; const MyAccountSection = () => { const t = useTranslate(); @@ -57,10 +56,6 @@ const MyAccountSection = () => { - - - - diff --git a/web/src/components/Settings/UserSessionsSection.tsx b/web/src/components/Settings/UserSessionsSection.tsx deleted file mode 100644 index 66bbff53f..000000000 --- a/web/src/components/Settings/UserSessionsSection.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { timestampDate } from "@bufbuild/protobuf/wkt"; -import { ClockIcon, MonitorIcon, SmartphoneIcon, TabletIcon, TrashIcon, WifiIcon } from "lucide-react"; -import { useEffect, useState } from "react"; -import { toast } from "react-hot-toast"; -import ConfirmDialog from "@/components/ConfirmDialog"; -import { Button } from "@/components/ui/button"; -import { userServiceClient } from "@/connect"; -import useCurrentUser from "@/hooks/useCurrentUser"; -import { Session } from "@/types/proto/api/v1/user_service_pb"; -import { useTranslate } from "@/utils/i18n"; -import SettingTable from "./SettingTable"; - -const listSessions = async (parent: string) => { - const { sessions } = await userServiceClient.listSessions({ parent }); - return sessions.sort( - (a, b) => - ((b.lastAccessedTime ? timestampDate(b.lastAccessedTime) : undefined)?.getTime() ?? 0) - - ((a.lastAccessedTime ? timestampDate(a.lastAccessedTime) : undefined)?.getTime() ?? 0), - ); -}; - -const UserSessionsSection = () => { - const t = useTranslate(); - const currentUser = useCurrentUser(); - const [sessions, setSessions] = useState([]); - const [revokeTarget, setRevokeTarget] = useState(undefined); - - useEffect(() => { - listSessions(currentUser.name).then((sessions) => { - setSessions(sessions); - }); - }, []); - - const handleRevokeSession = async (session: Session) => { - setRevokeTarget(session); - }; - - const confirmRevokeSession = async () => { - if (!revokeTarget) return; - await userServiceClient.revokeSession({ name: revokeTarget.name }); - setSessions(sessions.filter((session) => session.sessionId !== revokeTarget.sessionId)); - toast.success(t("setting.user-sessions-section.session-revoked")); - setRevokeTarget(undefined); - }; - - const getFormattedSessionId = (sessionId: string) => { - return `${sessionId.slice(0, 8)}...${sessionId.slice(-8)}`; - }; - - const getDeviceIcon = (deviceType: string) => { - switch (deviceType?.toLowerCase()) { - case "mobile": - return ; - case "tablet": - return ; - case "desktop": - default: - return ; - } - }; - - const formatDeviceInfo = (clientInfo: Session["clientInfo"]) => { - if (!clientInfo) return "Unknown Device"; - - const parts = []; - if (clientInfo.os) parts.push(clientInfo.os); - if (clientInfo.browser) parts.push(clientInfo.browser); - - return parts.length > 0 ? parts.join(" • ") : "Unknown Device"; - }; - - const isCurrentSession = (session: Session) => { - // A simple heuristic: the most recently accessed session is likely the current one - if (sessions.length === 0) return false; - const mostRecent = sessions[0]; - return session.sessionId === mostRecent.sessionId; - }; - - return ( -
-
-

{t("setting.user-sessions-section.title")}

-

{t("setting.user-sessions-section.description")}

-
- - ( -
- {getDeviceIcon(session.clientInfo?.deviceType || "")} -
- - {formatDeviceInfo(session.clientInfo)} - {isCurrentSession(session) && ( - - - {t("setting.user-sessions-section.current")} - - )} - - {getFormattedSessionId(session.sessionId)} -
-
- ), - }, - { - key: "lastAccessedTime", - header: t("setting.user-sessions-section.last-active"), - render: (_, session: Session) => ( -
- - {(session.lastAccessedTime ? timestampDate(session.lastAccessedTime) : undefined)?.toLocaleString()} -
- ), - }, - { - key: "actions", - header: "", - className: "text-right", - render: (_, session: Session) => ( - - ), - }, - ]} - data={sessions} - emptyMessage={t("setting.user-sessions-section.no-sessions")} - getRowKey={(session) => session.sessionId} - /> - - !open && setRevokeTarget(undefined)} - title={ - revokeTarget - ? t("setting.user-sessions-section.session-revocation", { - sessionId: getFormattedSessionId(revokeTarget.sessionId), - }) - : "" - } - description={revokeTarget ? t("setting.user-sessions-section.session-revocation-description") : ""} - confirmLabel={t("setting.user-sessions-section.revoke-session-button")} - cancelLabel={t("common.cancel")} - onConfirm={confirmRevokeSession} - confirmVariant="destructive" - /> -
- ); -}; - -export default UserSessionsSection; diff --git a/web/src/locales/ar.json b/web/src/locales/ar.json index 160923c92..335b84cca 100644 --- a/web/src/locales/ar.json +++ b/web/src/locales/ar.json @@ -251,21 +251,6 @@ "title": "رموز الوصول", "token": "رمز" }, - "user-sessions-section": { - "title": "الجلسات النشطة", - "description": "قائمة بجميع الجلسات النشطة لحسابك. تنتهي الجلسات تلقائيًا بعد أسبوعين من آخر نشاط. يمكنك إلغاء أي جلسة باستثناء الحالية.", - "device": "الجهاز", - "location": "الموقع", - "last-active": "آخر نشاط", - "expires": "ينتهي", - "current": "الحالية", - "never": "أبدًا", - "session-revocation": "هل أنت متأكد من إلغاء الجلسة {{sessionId}}؟ ستحتاج إلى تسجيل الدخول مرة أخرى على ذلك الجهاز.", - "session-revoked": "تم إلغاء الجلسة بنجاح", - "revoke-session": "إلغاء الجلسة", - "cannot-revoke-current": "لا يمكن إلغاء الجلسة الحالية", - "no-sessions": "لا توجد جلسات نشطة" - }, "account-section": { "change-password": "تغيير كلمة المرور", "email-note": "اختياري", diff --git a/web/src/locales/ca.json b/web/src/locales/ca.json index d839f44aa..729039939 100644 --- a/web/src/locales/ca.json +++ b/web/src/locales/ca.json @@ -251,21 +251,6 @@ "title": "Tokens d'accés", "token": "Token" }, - "user-sessions-section": { - "title": "Sessions actives", - "description": "Llista de totes les sessions actives del teu compte. Les sessions caduquen automàticament dues setmanes després de l'última activitat. Pots revocar qualsevol sessió excepte la sessió actual.", - "device": "Dispositiu", - "location": "Ubicació", - "last-active": "Última activitat", - "expires": "Caduca", - "current": "Actual", - "never": "Mai", - "session-revocation": "Estàs segur que vols revocar la sessió {{sessionId}}? Hauràs d'iniciar sessió de nou en aquest dispositiu.", - "session-revoked": "Sessió revocada correctament", - "revoke-session": "Revoca la sessió", - "cannot-revoke-current": "No es pot revocar la sessió actual", - "no-sessions": "No s'han trobat sessions actives" - }, "account-section": { "change-password": "Canvia la contrasenya", "email-note": "Opcional", diff --git a/web/src/locales/de.json b/web/src/locales/de.json index e00264df7..69e228b2f 100644 --- a/web/src/locales/de.json +++ b/web/src/locales/de.json @@ -236,21 +236,6 @@ "title": "Zugangstoken", "token": "Token" }, - "user-sessions-section": { - "title": "Aktive Sitzungen", - "description": "Liste aller aktiven Sitzungen für deinen Account. Sitzungen laufen automatisch 2 Wochen nach der letzten Aktivität ab. Du kannst jede Sitzung außer der aktuellen widerrufen.", - "device": "Gerät", - "location": "Standort", - "last-active": "Zuletzt aktiv", - "expires": "Läuft ab", - "current": "Aktuell", - "never": "Nie", - "session-revocation": "Bist du sicher, dass du die Sitzung {{sessionId}} widerrufen möchtest? Du musst dich auf diesem Gerät erneut anmelden.", - "session-revoked": "Sitzung erfolgreich widerrufen", - "revoke-session": "Sitzung widerrufen", - "cannot-revoke-current": "Aktuelle Sitzung kann nicht widerrufen werden", - "no-sessions": "Keine aktiven Sitzungen gefunden" - }, "account-section": { "change-password": "Passwort ändern", "email-note": "Optional", diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 2f494e882..3a60b8a8e 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -272,23 +272,6 @@ "title": "Access Tokens", "token": "Token" }, - "user-sessions-section": { - "title": "Active Sessions", - "description": "A list of all active sessions for your account. Sessions automatically expire 2 weeks after the last activity. You can revoke any session except the current one.", - "device": "Device", - "location": "Location", - "last-active": "Last Active", - "expires": "Expires", - "current": "Current", - "never": "Never", - "session-revocation": "Are you sure you want to revoke session `{{sessionId}}`?", - "session-revocation-description": "You will need to sign in again on that device.", - "session-revoked": "Session revoked successfully", - "revoke-session": "Revoke session", - "revoke-session-button": "Revoke", - "cannot-revoke-current": "Cannot revoke current session", - "no-sessions": "No active sessions found" - }, "account-section": { "change-password": "Change password", "email-note": "Optional", diff --git a/web/src/locales/es.json b/web/src/locales/es.json index 9faebcd03..d36b2e5c5 100644 --- a/web/src/locales/es.json +++ b/web/src/locales/es.json @@ -247,21 +247,6 @@ "title": "Tokens de acceso", "token": "Token" }, - "user-sessions-section": { - "title": "Sesiones activas", - "description": "Lista de todas las sesiones activas de tu cuenta. Las sesiones expiran automáticamente 2 semanas después de la última actividad. Puedes revocar cualquier sesión excepto la actual.", - "device": "Dispositivo", - "location": "Ubicación", - "last-active": "Última actividad", - "expires": "Expira", - "current": "Actual", - "never": "Nunca", - "session-revocation": "¿Estás seguro de revocar la sesión {{sessionId}}? Deberás iniciar sesión de nuevo en ese dispositivo.", - "session-revoked": "Sesión revocada correctamente", - "revoke-session": "Revocar sesión", - "cannot-revoke-current": "No se puede revocar la sesión actual", - "no-sessions": "No se encontraron sesiones activas" - }, "account-section": { "change-password": "Cambiar contraseña", "email-note": "Opcional", diff --git a/web/src/locales/fa.json b/web/src/locales/fa.json index 28cc76e3c..509da0f8b 100644 --- a/web/src/locales/fa.json +++ b/web/src/locales/fa.json @@ -226,21 +226,6 @@ "title": "توکن‌های دسترسی", "token": "توکن" }, - "user-sessions-section": { - "title": "نشست‌های فعال", - "description": "لیست تمام نشست‌های فعال حساب شما. نشست‌ها به طور خودکار دو هفته پس از آخرین فعالیت منقضی می‌شوند. می‌توانید هر نشستی به جز نشست فعلی را لغو کنید.", - "device": "دستگاه", - "location": "مکان", - "last-active": "آخرین فعالیت", - "expires": "منقضی می‌شود", - "current": "فعلی", - "never": "هرگز", - "session-revocation": "آیا از لغو نشست {{sessionId}} اطمینان دارید؟ باید دوباره در آن دستگاه وارد شوید.", - "session-revoked": "نشست با موفقیت لغو شد", - "revoke-session": "لغو نشست", - "cannot-revoke-current": "نشست فعلی را نمی‌توان لغو کرد", - "no-sessions": "نشست فعالی یافت نشد" - }, "account-section": { "change-password": "تغییر گذرواژه", "email-note": "اختیاری", diff --git a/web/src/locales/fr.json b/web/src/locales/fr.json index 7a7ee51e6..1277963aa 100644 --- a/web/src/locales/fr.json +++ b/web/src/locales/fr.json @@ -251,21 +251,6 @@ "title": "Jetons d'accès", "token": "Jeton" }, - "user-sessions-section": { - "title": "Sessions actives", - "description": "Liste de toutes les sessions actives de votre compte. Les sessions expirent automatiquement 2 semaines après la dernière activité. Vous pouvez révoquer toute session sauf la session actuelle.", - "device": "Appareil", - "location": "Emplacement", - "last-active": "Dernière activité", - "expires": "Expire", - "current": "Actuelle", - "never": "Jamais", - "session-revocation": "Êtes-vous sûr de vouloir révoquer la session {{sessionId}} ? Vous devrez vous reconnecter sur cet appareil.", - "session-revoked": "Session révoquée avec succès", - "revoke-session": "Révoquer la session", - "cannot-revoke-current": "Impossible de révoquer la session actuelle", - "no-sessions": "Aucune session active trouvée" - }, "account-section": { "change-password": "Changer le mot de passe", "email-note": "Optionnel", diff --git a/web/src/locales/hi.json b/web/src/locales/hi.json index 97af04a24..66a5920ff 100644 --- a/web/src/locales/hi.json +++ b/web/src/locales/hi.json @@ -252,21 +252,6 @@ "title": "एक्सेस टोकन", "token": "टोकन" }, - "user-sessions-section": { - "title": "सक्रिय सत्र", - "description": "आपके खाते के सभी सक्रिय सत्रों की सूची। सत्र अंतिम गतिविधि के 2 सप्ताह बाद स्वतः समाप्त हो जाते हैं। आप वर्तमान सत्र को छोड़कर किसी भी सत्र को रद्द कर सकते हैं।", - "device": "डिवाइस", - "location": "स्थान", - "last-active": "अंतिम सक्रिय", - "expires": "समाप्ति", - "current": "वर्तमान", - "never": "कभी नहीं", - "session-revocation": "क्या आप सत्र {{sessionId}} को रद्द करना चाहते हैं? आपको उस डिवाइस पर फिर से साइन इन करना होगा।", - "session-revoked": "सत्र सफलतापूर्वक रद्द किया गया", - "revoke-session": "सत्र रद्द करें", - "cannot-revoke-current": "वर्तमान सत्र को रद्द नहीं किया जा सकता", - "no-sessions": "कोई सक्रिय सत्र नहीं मिला" - }, "account-section": { "change-password": "पासवर्ड बदलें", "email-note": "वैकल्पिक", diff --git a/web/src/locales/hr.json b/web/src/locales/hr.json index 34f25a6c8..af4c8d80c 100644 --- a/web/src/locales/hr.json +++ b/web/src/locales/hr.json @@ -251,21 +251,6 @@ "title": "Tokeni pristupa", "token": "Token" }, - "user-sessions-section": { - "title": "Aktivne sesije", - "description": "Popis svih aktivnih sesija za tvoj račun. Sesije automatski istječu 2 tjedna nakon zadnje aktivnosti. Možeš opozvati bilo koju sesiju osim trenutne.", - "device": "Uređaj", - "location": "Lokacija", - "last-active": "Zadnja aktivnost", - "expires": "Istječe", - "current": "Trenutna", - "never": "Nikada", - "session-revocation": "Jesi li siguran da želiš opozvati sesiju {{sessionId}}? Morat ćeš se ponovno prijaviti na tom uređaju.", - "session-revoked": "Sesija uspješno opozvana", - "revoke-session": "Opozovi sesiju", - "cannot-revoke-current": "Trenutna sesija se ne može opozvati", - "no-sessions": "Nema aktivnih sesija" - }, "account-section": { "change-password": "Promijeni lozinku", "email-note": "Neobavezno", diff --git a/web/src/locales/hu.json b/web/src/locales/hu.json index f972a71d4..6325034cd 100644 --- a/web/src/locales/hu.json +++ b/web/src/locales/hu.json @@ -252,21 +252,6 @@ "title": "Hozzáférési tokenek", "token": "Token" }, - "user-sessions-section": { - "title": "Aktív munkamenetek", - "description": "A fiókodhoz tartozó összes aktív munkamenet listája. A munkamenetek automatikusan lejárnak az utolsó aktivitástól számított 2 hét után. A jelenlegi kivételével bármelyiket visszavonhatod.", - "device": "Eszköz", - "location": "Hely", - "last-active": "Utoljára aktív", - "expires": "Lejár", - "current": "Jelenlegi", - "never": "Soha", - "session-revocation": "Biztosan visszavonod a(z) {{sessionId}} munkamenetet? Újra be kell jelentkezned azon az eszközön.", - "session-revoked": "A munkamenet sikeresen visszavonva", - "revoke-session": "Munkamenet visszavonása", - "cannot-revoke-current": "A jelenlegi munkamenet nem vonható vissza", - "no-sessions": "Nincs aktív munkamenet" - }, "account-section": { "change-password": "Jelszó megváltoztatása", "email-note": "Nem kötelező", diff --git a/web/src/locales/id.json b/web/src/locales/id.json index 5d03058cc..2ebc2457e 100644 --- a/web/src/locales/id.json +++ b/web/src/locales/id.json @@ -251,21 +251,6 @@ "title": "Token Akses", "token": "Token" }, - "user-sessions-section": { - "title": "Sesi Aktif", - "description": "Daftar semua sesi aktif untuk akun Anda. Sesi akan otomatis berakhir 2 minggu setelah aktivitas terakhir. Anda dapat mencabut sesi mana pun kecuali sesi saat ini.", - "device": "Perangkat", - "location": "Lokasi", - "last-active": "Terakhir Aktif", - "expires": "Berakhir", - "current": "Saat ini", - "never": "Tidak Pernah", - "session-revocation": "Apakah Anda yakin ingin mencabut sesi {{sessionId}}? Anda perlu masuk kembali di perangkat tersebut.", - "session-revoked": "Sesi berhasil dicabut", - "revoke-session": "Cabut sesi", - "cannot-revoke-current": "Tidak dapat mencabut sesi saat ini", - "no-sessions": "Tidak ada sesi aktif yang ditemukan" - }, "account-section": { "change-password": "Ubah kata sandi", "email-note": "Opsional", diff --git a/web/src/locales/it.json b/web/src/locales/it.json index c0e289449..753fb274d 100644 --- a/web/src/locales/it.json +++ b/web/src/locales/it.json @@ -270,23 +270,6 @@ "title": "Token di accesso", "token": "Token" }, - "user-sessions-section": { - "title": "Sessioni attive", - "description": "Elenco di tutte le sessioni attive del tuo account. Le sessioni scadono automaticamente dopo 2 settimane dall'ultima attività. Puoi revocare qualsiasi sessione tranne quella attuale.", - "device": "Dispositivo", - "location": "Posizione", - "last-active": "Ultima attività", - "expires": "Scade", - "current": "Attuale", - "never": "Mai", - "session-revocation": "Confermi di voler revocare la sessione `{{sessionId}}`?", - "session-revocation-description": "Dovrai accedere di nuovo su quel dispositivo.", - "session-revoked": "Sessione revocata con successo", - "revoke-session": "Revoca sessione", - "revoke-session-button": "Revoca", - "cannot-revoke-current": "Impossibile revocare la sessione attuale", - "no-sessions": "Nessuna sessione attiva trovata" - }, "account-section": { "change-password": "Cambia password", "email-note": "Opzionale", diff --git a/web/src/locales/ja.json b/web/src/locales/ja.json index 680206966..81dc9787e 100644 --- a/web/src/locales/ja.json +++ b/web/src/locales/ja.json @@ -251,21 +251,6 @@ "title": "アクセストークン", "token": "トークン" }, - "user-sessions-section": { - "title": "アクティブセッション", - "description": "あなたのアカウントのすべてのアクティブなセッション一覧です。セッションは最後の操作から2週間後に自動的に期限切れになります。現在のセッション以外は取り消し可能です。", - "device": "デバイス", - "location": "場所", - "last-active": "最終アクティブ", - "expires": "有効期限", - "current": "現在", - "never": "無期限", - "session-revocation": "セッション {{sessionId}} を取り消しますか?そのデバイスで再度サインインが必要です。", - "session-revoked": "セッションを取り消しました", - "revoke-session": "セッションを取り消す", - "cannot-revoke-current": "現在のセッションは取り消せません", - "no-sessions": "アクティブなセッションはありません" - }, "account-section": { "change-password": "パスワードを変更", "email-note": "オプション", diff --git a/web/src/locales/ka-GE.json b/web/src/locales/ka-GE.json index ef66ac2cb..217a931d0 100644 --- a/web/src/locales/ka-GE.json +++ b/web/src/locales/ka-GE.json @@ -251,21 +251,6 @@ "title": "წვდომის ტოკენები", "token": "ტოკენი" }, - "user-sessions-section": { - "title": "აქტიური სესიები", - "description": "თქვენი ანგარიშის ყველა აქტიური სესიის სია. სესიები ავტომატურად იწურება ბოლო აქტივობიდან 2 კვირის შემდეგ. შეგიძლიათ გააუქმოთ ნებისმიერი სესია გარდა მიმდინარე სესიისა.", - "device": "მოწყობილობა", - "location": "მდებარეობა", - "last-active": "ბოლო აქტიურობა", - "expires": "ვადა იწურება", - "current": "მიმდინარე", - "never": "არასდროს", - "session-revocation": "დარწმუნებული ხართ, რომ გსურთ სესიის გაუქმება {{sessionId}}? მოგიწევთ ხელახლა შესვლა ამ მოწყობილობაზე.", - "session-revoked": "სესია წარმატებით გაუქმდა", - "revoke-session": "სესიის გაუქმება", - "cannot-revoke-current": "მიმდინარე სესიის გაუქმება შეუძლებელია", - "no-sessions": "აქტიური სესიები ვერ მოიძებნა" - }, "account-section": { "change-password": "პაროლის შეცვლა", "email-note": "არასავალდებულო", diff --git a/web/src/locales/ko.json b/web/src/locales/ko.json index 685ae39ca..a435c955c 100644 --- a/web/src/locales/ko.json +++ b/web/src/locales/ko.json @@ -259,21 +259,6 @@ "title": "액세스 토큰", "token": "토큰" }, - "user-sessions-section": { - "title": "활성 세션", - "description": "계정의 모든 활성 세션 목록입니다. 세션은 마지막 활동 후 2주 후에 자동으로 만료됩니다. 현재 세션을 제외한 모든 세션을 취소할 수 있습니다.", - "device": "기기", - "location": "위치", - "last-active": "마지막 활동", - "expires": "만료", - "current": "현재", - "never": "영구", - "session-revocation": "세션 {{sessionId}}을 취소하시겠습니까? 해당 기기에서 다시 로그인해야 합니다.", - "session-revoked": "세션이 성공적으로 취소되었습니다", - "revoke-session": "세션 취소", - "cannot-revoke-current": "현재 세션은 취소할 수 없습니다", - "no-sessions": "활성 세션이 없습니다" - }, "account-section": { "change-password": "비밀번호 변경", "email-note": "선택 사항", diff --git a/web/src/locales/mr.json b/web/src/locales/mr.json index b17881a10..9ac5da736 100644 --- a/web/src/locales/mr.json +++ b/web/src/locales/mr.json @@ -251,21 +251,6 @@ "title": "ऍक्सेस टोकन्स", "token": "टोकन" }, - "user-sessions-section": { - "title": "सक्रिय सत्रे", - "description": "तुमच्या खात्यातील सर्व सक्रिय सत्रांची यादी. सत्रे शेवटच्या क्रियेनंतर 2 आठवड्यांनी आपोआप कालबाह्य होतात. तुम्ही चालू सत्र वगळता कोणतेही सत्र रद्द करू शकता.", - "device": "डिव्हाइस", - "location": "स्थान", - "last-active": "शेवटचे सक्रिय", - "expires": "कालबाह्यता", - "current": "चालू", - "never": "कधीच नाही", - "session-revocation": "तुम्हाला सत्र {{sessionId}} रद्द करायचे आहे का? त्या डिव्हाइसवर पुन्हा साइन इन करावे लागेल.", - "session-revoked": "सत्र यशस्वीरित्या रद्द केले", - "revoke-session": "सत्र रद्द करा", - "cannot-revoke-current": "चालू सत्र रद्द करता येणार नाही", - "no-sessions": "कोणतीही सक्रिय सत्रे आढळली नाहीत" - }, "account-section": { "change-password": "पासवर्ड बदला", "email-note": "ऐच्छिक", diff --git a/web/src/locales/nb.json b/web/src/locales/nb.json index 69774431b..e919cdb81 100644 --- a/web/src/locales/nb.json +++ b/web/src/locales/nb.json @@ -251,21 +251,6 @@ "title": "Access tokens", "token": "Token" }, - "user-sessions-section": { - "title": "Aktive økter", - "description": "En liste over alle aktive økter for din konto. Økter utløper automatisk 2 uker etter siste aktivitet. Du kan tilbakekalle enhver økt bortsett fra den nåværende.", - "device": "Enhet", - "location": "Plassering", - "last-active": "Sist aktiv", - "expires": "Utløper", - "current": "Nåværende", - "never": "Aldri", - "session-revocation": "Er du sikker på at du vil tilbakekalle økt {{sessionId}}? Du må logge inn på nytt på den enheten.", - "session-revoked": "Økt tilbakekalt", - "revoke-session": "Tilbakekall økt", - "cannot-revoke-current": "Kan ikke tilbakekalle nåværende økt", - "no-sessions": "Ingen aktive økter funnet" - }, "account-section": { "change-password": "Endre passord", "email-note": "Valgfritt", diff --git a/web/src/locales/nl.json b/web/src/locales/nl.json index acd6094f4..57eebc5e0 100644 --- a/web/src/locales/nl.json +++ b/web/src/locales/nl.json @@ -251,21 +251,6 @@ "title": "Accesstokens", "token": "Token" }, - "user-sessions-section": { - "title": "Actieve sessies", - "description": "Een lijst van alle actieve sessies voor je account. Sessies verlopen automatisch 2 weken na de laatste activiteit. Je kunt elke sessie intrekken behalve de huidige.", - "device": "Apparaat", - "location": "Locatie", - "last-active": "Laatst actief", - "expires": "Verloopt", - "current": "Huidig", - "never": "Nooit", - "session-revocation": "Weet je zeker dat je sessie {{sessionId}} wilt intrekken? Je moet opnieuw inloggen op dat apparaat.", - "session-revoked": "Sessie succesvol ingetrokken", - "revoke-session": "Sessie intrekken", - "cannot-revoke-current": "Kan huidige sessie niet intrekken", - "no-sessions": "Geen actieve sessies gevonden" - }, "account-section": { "change-password": "Wachtwoord wijzigen", "email-note": "Optioneel", diff --git a/web/src/locales/pl.json b/web/src/locales/pl.json index 843e8b971..66b340d57 100644 --- a/web/src/locales/pl.json +++ b/web/src/locales/pl.json @@ -251,21 +251,6 @@ "title": "Tokeny dostępu", "token": "Token" }, - "user-sessions-section": { - "title": "Aktywne sesje", - "description": "Lista wszystkich aktywnych sesji Twojego konta. Sesje wygasają automatycznie po 2 tygodniach od ostatniej aktywności. Możesz cofnąć dowolną sesję oprócz bieżącej.", - "device": "Urządzenie", - "location": "Lokalizacja", - "last-active": "Ostatnia aktywność", - "expires": "Wygasa", - "current": "Bieżąca", - "never": "Nigdy", - "session-revocation": "Czy na pewno chcesz cofnąć sesję {{sessionId}}? Będziesz musiał zalogować się ponownie na tym urządzeniu.", - "session-revoked": "Sesja cofnięta pomyślnie", - "revoke-session": "Cofnij sesję", - "cannot-revoke-current": "Nie można cofnąć bieżącej sesji", - "no-sessions": "Nie znaleziono aktywnych sesji" - }, "account-section": { "change-password": "Zmień hasło", "email-note": "Opcjonalne", diff --git a/web/src/locales/pt-BR.json b/web/src/locales/pt-BR.json index 0cfe8cdce..6cc92f6f6 100644 --- a/web/src/locales/pt-BR.json +++ b/web/src/locales/pt-BR.json @@ -251,21 +251,6 @@ "title": "Tokens de acesso", "token": "Token" }, - "user-sessions-section": { - "title": "Sessões ativas", - "description": "Uma lista de todas as sessões ativas da sua conta. As sessões expiram automaticamente 2 semanas após a última atividade. Você pode revogar qualquer sessão, exceto a atual.", - "device": "Dispositivo", - "location": "Localização", - "last-active": "Última atividade", - "expires": "Expira", - "current": "Atual", - "never": "Nunca", - "session-revocation": "Tem certeza de que deseja revogar a sessão {{sessionId}}? Você precisará entrar novamente nesse dispositivo.", - "session-revoked": "Sessão revogada com sucesso", - "revoke-session": "Revogar sessão", - "cannot-revoke-current": "Não é possível revogar a sessão atual", - "no-sessions": "Nenhuma sessão ativa encontrada" - }, "account-section": { "change-password": "Alterar senha", "email-note": "Opcional", diff --git a/web/src/locales/pt-PT.json b/web/src/locales/pt-PT.json index bb955480b..b2bc767c0 100644 --- a/web/src/locales/pt-PT.json +++ b/web/src/locales/pt-PT.json @@ -251,21 +251,6 @@ "title": "Tokens de Acesso", "token": "Token" }, - "user-sessions-section": { - "title": "Sessões ativas", - "description": "Uma lista de todas as sessões ativas da sua conta. As sessões expiram automaticamente 2 semanas após a última atividade. Pode revogar qualquer sessão exceto a atual.", - "device": "Dispositivo", - "location": "Localização", - "last-active": "Última atividade", - "expires": "Expira", - "current": "Atual", - "never": "Nunca", - "session-revocation": "Tem a certeza de que deseja revogar a sessão {{sessionId}}? Terá de iniciar sessão novamente nesse dispositivo.", - "session-revoked": "Sessão revogada com sucesso", - "revoke-session": "Revogar sessão", - "cannot-revoke-current": "Não é possível revogar a sessão atual", - "no-sessions": "Nenhuma sessão ativa encontrada" - }, "account-section": { "change-password": "Alterar palavra-passe", "email-note": "Opcional", diff --git a/web/src/locales/ru.json b/web/src/locales/ru.json index bbbecca00..74f575da0 100644 --- a/web/src/locales/ru.json +++ b/web/src/locales/ru.json @@ -229,21 +229,6 @@ "title": "Токены доступа", "token": "Токен" }, - "user-sessions-section": { - "title": "Активные сессии", - "description": "Список всех активных сессий для вашей учетной записи. Сессии истекают через 2 недели после последней активности. Вы можете завершить любую сессию, кроме текущей.", - "device": "Устройство", - "location": "Местоположение", - "last-active": "Последняя активность", - "expires": "Expires", - "current": "Текущая", - "never": "Никогда", - "session-revocation": "Вы действительно хотите завершить сессию {{sessionId}}?\nПридётся повторно войти на связанном устройстве.", - "session-revoked": "Сессия завершена", - "revoke-session": "Завершить сессию", - "cannot-revoke-current": "Нельзя завершить текущую сессию", - "no-sessions": "Нет активных сессий" - }, "account-section": { "change-password": "Изменить пароль", "email-note": "Опционально", diff --git a/web/src/locales/sl.json b/web/src/locales/sl.json index b7a2783e4..daab1205e 100644 --- a/web/src/locales/sl.json +++ b/web/src/locales/sl.json @@ -251,21 +251,6 @@ "title": "Dostopni žetoni", "token": "Žeton" }, - "user-sessions-section": { - "title": "Aktivne seje", - "description": "Seznam vseh aktivnih sej vašega računa. Seje samodejno potečejo 2 tedna po zadnji aktivnosti. Lahko prekličete katerokoli sejo razen trenutne.", - "device": "Naprava", - "location": "Lokacija", - "last-active": "Zadnja aktivnost", - "expires": "Poteče", - "current": "Trenutna", - "never": "Nikoli", - "session-revocation": "Ali ste prepričani, da želite preklicati sejo {{sessionId}}? Ponovno se boste morali prijaviti na tej napravi.", - "session-revoked": "Seja uspešno preklicana", - "revoke-session": "Prekliči sejo", - "cannot-revoke-current": "Trenutne seje ni mogoče preklicati", - "no-sessions": "Ni aktivnih sej" - }, "account-section": { "change-password": "Zamenjaj geslo", "email-note": "Opcijsko", diff --git a/web/src/locales/sv.json b/web/src/locales/sv.json index ed152318f..e554ab632 100644 --- a/web/src/locales/sv.json +++ b/web/src/locales/sv.json @@ -251,21 +251,6 @@ "title": "Åtkomsttoken", "token": "Token" }, - "user-sessions-section": { - "title": "Aktiva sessioner", - "description": "En lista över alla aktiva sessioner för ditt konto. Sessioner upphör automatiskt 2 veckor efter senaste aktivitet. Du kan återkalla alla sessioner utom den nuvarande.", - "device": "Enhet", - "location": "Plats", - "last-active": "Senast aktiv", - "expires": "Går ut", - "current": "Nuvarande", - "never": "Aldrig", - "session-revocation": "Är du säker på att återkalla session {{sessionId}}? Du måste logga in igen på den enheten.", - "session-revoked": "Session återkallad", - "revoke-session": "Återkalla session", - "cannot-revoke-current": "Kan inte återkalla nuvarande session", - "no-sessions": "Inga aktiva sessioner hittades" - }, "account-section": { "change-password": "Ändra lösenord", "email-note": "Valfritt", diff --git a/web/src/locales/th.json b/web/src/locales/th.json index abd56afbe..5424cf9b5 100644 --- a/web/src/locales/th.json +++ b/web/src/locales/th.json @@ -251,21 +251,6 @@ "title": "โทเค็นการเข้าถึง", "token": "โทเค็น" }, - "user-sessions-section": { - "title": "เซสชันที่ใช้งานอยู่", - "description": "รายการเซสชันที่ใช้งานอยู่ทั้งหมดสำหรับบัญชีของคุณ เซสชันจะหมดอายุอัตโนมัติหลังจากไม่มีการใช้งาน 2 สัปดาห์ คุณสามารถเพิกถอนเซสชันใดก็ได้ยกเว้นเซสชันปัจจุบัน", - "device": "อุปกรณ์", - "location": "ตำแหน่ง", - "last-active": "ใช้งานล่าสุด", - "expires": "หมดอายุ", - "current": "ปัจจุบัน", - "never": "ไม่หมดอายุ", - "session-revocation": "คุณแน่ใจหรือว่าจะเพิกถอนเซสชัน {{sessionId}}? คุณจะต้องเข้าสู่ระบบใหม่บนอุปกรณ์นั้น", - "session-revoked": "เพิกถอนเซสชันสำเร็จ", - "revoke-session": "เพิกถอนเซสชัน", - "cannot-revoke-current": "ไม่สามารถเพิกถอนเซสชันปัจจุบันได้", - "no-sessions": "ไม่พบเซสชันที่ใช้งานอยู่" - }, "account-section": { "change-password": "เปลี่ยนรหัสผ่าน", "email-note": "ไม่บังคับ", diff --git a/web/src/locales/tr.json b/web/src/locales/tr.json index d6903c3cb..c99b19ca7 100644 --- a/web/src/locales/tr.json +++ b/web/src/locales/tr.json @@ -251,21 +251,6 @@ "title": "Erişim Tokenleri", "token": "Token" }, - "user-sessions-section": { - "title": "Aktif Oturumlar", - "description": "Hesabınız için tüm aktif oturumların listesi. Oturumlar, son etkinlikten 2 hafta sonra otomatik olarak sona erer. Mevcut oturum hariç herhangi bir oturumu iptal edebilirsiniz.", - "device": "Cihaz", - "location": "Konum", - "last-active": "Son Etkinlik", - "expires": "Sona Erme", - "current": "Mevcut", - "never": "Asla", - "session-revocation": "{{sessionId}} oturumunu iptal etmek istediğinizden emin misiniz? O cihazda tekrar giriş yapmanız gerekecek.", - "session-revoked": "Oturum başarıyla iptal edildi", - "revoke-session": "Oturumu iptal et", - "cannot-revoke-current": "Mevcut oturum iptal edilemez", - "no-sessions": "Aktif oturum bulunamadı" - }, "account-section": { "change-password": "Şifre değiştir", "email-note": "İsteğe bağlı", diff --git a/web/src/locales/uk.json b/web/src/locales/uk.json index 3ac2b25e8..c599aefbe 100644 --- a/web/src/locales/uk.json +++ b/web/src/locales/uk.json @@ -251,21 +251,6 @@ "title": "Токени доступу", "token": "Токен" }, - "user-sessions-section": { - "title": "Активні сесії", - "description": "Список усіх активних сесій для вашого облікового запису. Сесії автоматично завершуються через 2 тижні після останньої активності. Ви можете відкликати будь-яку сесію, окрім поточної.", - "device": "Пристрій", - "location": "Місцезнаходження", - "last-active": "Остання активність", - "expires": "Завершується", - "current": "Поточна", - "never": "Ніколи", - "session-revocation": "Ви впевнені, що хочете відкликати сесію {{sessionId}}? Вам потрібно буде увійти знову на цьому пристрої.", - "session-revoked": "Сесію успішно відкликано", - "revoke-session": "Відкликати сесію", - "cannot-revoke-current": "Не можна відкликати поточну сесію", - "no-sessions": "Активних сесій не знайдено" - }, "account-section": { "change-password": "Змінити пароль", "email-note": "Необов'язково", diff --git a/web/src/locales/zh-Hans.json b/web/src/locales/zh-Hans.json index 357ba900d..7937900da 100644 --- a/web/src/locales/zh-Hans.json +++ b/web/src/locales/zh-Hans.json @@ -256,21 +256,6 @@ "title": "访问令牌", "token": "令牌" }, - "user-sessions-section": { - "title": "用户会话", - "description": "当前账号下全部的会话,你可以撤销除当前会话以外的所有会话。", - "device": "设备", - "location": "位置", - "last-active": "最后活跃时间", - "expires": "过期时间", - "current": "当前设备", - "never": "从未", - "session-revocation": "您确定要撤销会话 {{sessionId}} 吗?删除后您将需要在该设备上再次登录。", - "session-revoked": "会话已成功撤销", - "revoke-session": "撤销会话", - "cannot-revoke-current": "无法撤销当前会话", - "no-sessions": "当前没有会话" - }, "account-section": { "change-password": "修改密码", "email-note": "可选", diff --git a/web/src/locales/zh-Hant.json b/web/src/locales/zh-Hant.json index db4be5123..4954e1e1f 100644 --- a/web/src/locales/zh-Hant.json +++ b/web/src/locales/zh-Hant.json @@ -260,23 +260,6 @@ "title": "存取令牌", "token": "令牌" }, - "user-sessions-section": { - "title": "工作階段", - "description": "此處列出您帳號的所有工作階段。工作階段將於最後一次活動的兩週後自動過期。您可以撤銷除了現階段之外的所有工作階段。", - "device": "裝置", - "location": "位置", - "last-active": "最後活躍時間", - "expires": "過期時間", - "current": "當前裝置", - "never": "永不過期", - "session-revocation": "您確定要撤銷工作階段 `{{sessionId}}` 嗎?", - "session-revocation-description": "您需要在該裝置上重新登入。", - "session-revoked": "工作階段撤銷成功", - "revoke-session": "撤銷工作階段", - "revoke-session-button": "撤銷", - "cannot-revoke-current": "無法撤銷當前裝置的工作階段", - "no-sessions": "無工作階段" - }, "account-section": { "change-password": "變更密碼", "email-note": "選填", diff --git a/web/src/store/user.ts b/web/src/store/user.ts index ae83a62b3..a0a438927 100644 --- a/web/src/store/user.ts +++ b/web/src/store/user.ts @@ -9,10 +9,8 @@ import { User, UserNotification, UserSetting, - UserSetting_AccessTokensSetting, UserSetting_GeneralSetting, UserSetting_Key, - UserSetting_SessionsSetting, UserSetting_WebhooksSetting, UserSettingSchema, UserStats, @@ -31,8 +29,6 @@ function getSettingValue(setting: UserSetting, caseType: string): T | undefin class LocalState { currentUser?: string; userGeneralSetting?: UserSetting_GeneralSetting; - userSessionsSetting?: UserSetting_SessionsSetting; - userAccessTokensSetting?: UserSetting_AccessTokensSetting; userWebhooksSetting?: UserSetting_WebhooksSetting; shortcuts: Shortcut[] = []; notifications: UserNotification[] = []; @@ -214,16 +210,10 @@ const userStore = (() => { // Extract and store each setting type using the oneof pattern const generalSetting = settings.find((s) => s.value.case === "generalSetting"); - const sessionsSetting = settings.find((s) => s.value.case === "sessionsSetting"); - const accessTokensSetting = settings.find((s) => s.value.case === "accessTokensSetting"); const webhooksSetting = settings.find((s) => s.value.case === "webhooksSetting"); state.setPartial({ userGeneralSetting: generalSetting ? getSettingValue(generalSetting, "generalSetting") : undefined, - userSessionsSetting: sessionsSetting ? getSettingValue(sessionsSetting, "sessionsSetting") : undefined, - userAccessTokensSetting: accessTokensSetting - ? getSettingValue(accessTokensSetting, "accessTokensSetting") - : undefined, userWebhooksSetting: webhooksSetting ? getSettingValue(webhooksSetting, "webhooksSetting") : undefined, shortcuts: shortcuts, }); @@ -390,8 +380,6 @@ export const logout = async () => { userStore.state.setPartial({ currentUser: undefined, userGeneralSetting: undefined, - userSessionsSetting: undefined, - userAccessTokensSetting: undefined, userWebhooksSetting: undefined, shortcuts: [], notifications: [], diff --git a/web/src/types/proto/api/v1/user_service_pb.ts b/web/src/types/proto/api/v1/user_service_pb.ts index 7c17ef057..94e9b88f2 100644 --- a/web/src/types/proto/api/v1/user_service_pb.ts +++ b/web/src/types/proto/api/v1/user_service_pb.ts @@ -18,7 +18,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file api/v1/user_service.proto. */ export const file_api_v1_user_service: GenFile = /*@__PURE__*/ - fileDesc("ChlhcGkvdjEvdXNlcl9zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEi4AMKBFVzZXISEQoEbmFtZRgBIAEoCUID4EEIEioKBHJvbGUYAiABKA4yFy5tZW1vcy5hcGkudjEuVXNlci5Sb2xlQgPgQQISFQoIdXNlcm5hbWUYAyABKAlCA+BBAhISCgVlbWFpbBgEIAEoCUID4EEBEhkKDGRpc3BsYXlfbmFtZRgFIAEoCUID4EEBEhcKCmF2YXRhcl91cmwYBiABKAlCA+BBARIYCgtkZXNjcmlwdGlvbhgHIAEoCUID4EEBEhUKCHBhc3N3b3JkGAggASgJQgPgQQQSJwoFc3RhdGUYCSABKA4yEy5tZW1vcy5hcGkudjEuU3RhdGVCA+BBAhI0CgtjcmVhdGVfdGltZRgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAyI7CgRSb2xlEhQKEFJPTEVfVU5TUEVDSUZJRUQQABIICgRIT1NUEAESCQoFQURNSU4QAhIICgRVU0VSEAM6N+pBNAoRbWVtb3MuYXBpLnYxL1VzZXISDHVzZXJzL3t1c2VyfRoEbmFtZSoFdXNlcnMyBHVzZXIicwoQTGlzdFVzZXJzUmVxdWVzdBIWCglwYWdlX3NpemUYASABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAIgASgJQgPgQQESEwoGZmlsdGVyGAMgASgJQgPgQQESGQoMc2hvd19kZWxldGVkGAQgASgIQgPgQQEiYwoRTGlzdFVzZXJzUmVzcG9uc2USIQoFdXNlcnMYASADKAsyEi5tZW1vcy5hcGkudjEuVXNlchIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkSEgoKdG90YWxfc2l6ZRgDIAEoBSJtCg5HZXRVc2VyUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEjIKCXJlYWRfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBASKIAQoRQ3JlYXRlVXNlclJlcXVlc3QSKAoEdXNlchgBIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyQgbgQQLgQQQSFAoHdXNlcl9pZBgCIAEoCUID4EEBEhoKDXZhbGlkYXRlX29ubHkYAyABKAhCA+BBARIXCgpyZXF1ZXN0X2lkGAQgASgJQgPgQQEijAEKEVVwZGF0ZVVzZXJSZXF1ZXN0EiUKBHVzZXIYASABKAsyEi5tZW1vcy5hcGkudjEuVXNlckID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECEhoKDWFsbG93X21pc3NpbmcYAyABKAhCA+BBASJQChFEZWxldGVVc2VyUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhIKBWZvcmNlGAIgASgIQgPgQQEi2AMKCVVzZXJTdGF0cxIRCgRuYW1lGAEgASgJQgPgQQgSOwoXbWVtb19kaXNwbGF5X3RpbWVzdGFtcHMYAiADKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEj4KD21lbW9fdHlwZV9zdGF0cxgDIAEoCzIlLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMuTWVtb1R5cGVTdGF0cxI4Cgl0YWdfY291bnQYBCADKAsyJS5tZW1vcy5hcGkudjEuVXNlclN0YXRzLlRhZ0NvdW50RW50cnkSFAoMcGlubmVkX21lbW9zGAUgAygJEhgKEHRvdGFsX21lbW9fY291bnQYBiABKAUaLwoNVGFnQ291bnRFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAU6AjgBGl8KDU1lbW9UeXBlU3RhdHMSEgoKbGlua19jb3VudBgBIAEoBRISCgpjb2RlX2NvdW50GAIgASgFEhIKCnRvZG9fY291bnQYAyABKAUSEgoKdW5kb19jb3VudBgEIAEoBTo/6kE8ChZtZW1vcy5hcGkudjEvVXNlclN0YXRzEgx1c2Vycy97dXNlcn0qCXVzZXJTdGF0czIJdXNlclN0YXRzIj4KE0dldFVzZXJTdGF0c1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlciIZChdMaXN0QWxsVXNlclN0YXRzUmVxdWVzdCJCChhMaXN0QWxsVXNlclN0YXRzUmVzcG9uc2USJgoFc3RhdHMYASADKAsyFy5tZW1vcy5hcGkudjEuVXNlclN0YXRzIq4GCgtVc2VyU2V0dGluZxIRCgRuYW1lGAEgASgJQgPgQQgSQwoPZ2VuZXJhbF9zZXR0aW5nGAIgASgLMigubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nLkdlbmVyYWxTZXR0aW5nSAASRQoQc2Vzc2lvbnNfc2V0dGluZxgDIAEoCzIpLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZy5TZXNzaW9uc1NldHRpbmdIABJOChVhY2Nlc3NfdG9rZW5zX3NldHRpbmcYBCABKAsyLS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmcuQWNjZXNzVG9rZW5zU2V0dGluZ0gAEkUKEHdlYmhvb2tzX3NldHRpbmcYBSABKAsyKS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmcuV2ViaG9va3NTZXR0aW5nSAAaVwoOR2VuZXJhbFNldHRpbmcSEwoGbG9jYWxlGAEgASgJQgPgQQESHAoPbWVtb192aXNpYmlsaXR5GAMgASgJQgPgQQESEgoFdGhlbWUYBCABKAlCA+BBARo6Cg9TZXNzaW9uc1NldHRpbmcSJwoIc2Vzc2lvbnMYASADKAsyFS5tZW1vcy5hcGkudjEuU2Vzc2lvbhpYChNBY2Nlc3NUb2tlbnNTZXR0aW5nEkEKFnBlcnNvbmFsX2FjY2Vzc190b2tlbnMYASADKAsyIS5tZW1vcy5hcGkudjEuUGVyc29uYWxBY2Nlc3NUb2tlbho+Cg9XZWJob29rc1NldHRpbmcSKwoId2ViaG9va3MYASADKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siVgoDS2V5EhMKD0tFWV9VTlNQRUNJRklFRBAAEgsKB0dFTkVSQUwQARIMCghTRVNTSU9OUxACEhEKDUFDQ0VTU19UT0tFTlMQAxIMCghXRUJIT09LUxAEOlnqQVYKGG1lbW9zLmFwaS52MS9Vc2VyU2V0dGluZxIfdXNlcnMve3VzZXJ9L3NldHRpbmdzL3tzZXR0aW5nfSoMdXNlclNldHRpbmdzMgt1c2VyU2V0dGluZ0IHCgV2YWx1ZSJHChVHZXRVc2VyU2V0dGluZ1JlcXVlc3QSLgoEbmFtZRgBIAEoCUIg4EEC+kEaChhtZW1vcy5hcGkudjEvVXNlclNldHRpbmcigQEKGFVwZGF0ZVVzZXJTZXR0aW5nUmVxdWVzdBIvCgdzZXR0aW5nGAEgASgLMhkubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQIidQoXTGlzdFVzZXJTZXR0aW5nc1JlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBASJ0ChhMaXN0VXNlclNldHRpbmdzUmVzcG9uc2USKwoIc2V0dGluZ3MYASADKAsyGS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmcSFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJEhIKCnRvdGFsX3NpemUYAyABKAUi8gIKE1BlcnNvbmFsQWNjZXNzVG9rZW4SEQoEbmFtZRgBIAEoCUID4EEIEhgKC2Rlc2NyaXB0aW9uGAIgASgJQgPgQQESMwoKY3JlYXRlZF9hdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxIzCgpleHBpcmVzX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEBEjUKDGxhc3RfdXNlZF9hdBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAzqMAepBiAEKIG1lbW9zLmFwaS52MS9QZXJzb25hbEFjY2Vzc1Rva2VuEjl1c2Vycy97dXNlcn0vcGVyc29uYWxBY2Nlc3NUb2tlbnMve3BlcnNvbmFsX2FjY2Vzc190b2tlbn0qFHBlcnNvbmFsQWNjZXNzVG9rZW5zMhNwZXJzb25hbEFjY2Vzc1Rva2VuIn0KH0xpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1JlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBASKSAQogTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zUmVzcG9uc2USQQoWcGVyc29uYWxfYWNjZXNzX3Rva2VucxgBIAMoCzIhLm1lbW9zLmFwaS52MS5QZXJzb25hbEFjY2Vzc1Rva2VuEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIoUBCiBDcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISGAoLZGVzY3JpcHRpb24YAiABKAlCA+BBARIcCg9leHBpcmVzX2luX2RheXMYAyABKAVCA+BBASJ0CiFDcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVzcG9uc2USQAoVcGVyc29uYWxfYWNjZXNzX3Rva2VuGAEgASgLMiEubWVtb3MuYXBpLnYxLlBlcnNvbmFsQWNjZXNzVG9rZW4SDQoFdG9rZW4YAiABKAkiWgogRGVsZXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlcXVlc3QSNgoEbmFtZRgBIAEoCUIo4EEC+kEiCiBtZW1vcy5hcGkudjEvUGVyc29uYWxBY2Nlc3NUb2tlbiKdAwoHU2Vzc2lvbhIRCgRuYW1lGAEgASgJQgPgQQgSFwoKc2Vzc2lvbl9pZBgCIAEoCUID4EEDEjQKC2NyZWF0ZV90aW1lGAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDEjsKEmxhc3RfYWNjZXNzZWRfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI6CgtjbGllbnRfaW5mbxgFIAEoCzIgLm1lbW9zLmFwaS52MS5TZXNzaW9uLkNsaWVudEluZm9CA+BBAxp1CgpDbGllbnRJbmZvEhIKCnVzZXJfYWdlbnQYASABKAkSEgoKaXBfYWRkcmVzcxgCIAEoCRIYCgtkZXZpY2VfdHlwZRgDIAEoCUID4EEBEg8KAm9zGAQgASgJQgPgQQESFAoHYnJvd3NlchgFIAEoCUID4EEBOkDqQT0KFG1lbW9zLmFwaS52MS9TZXNzaW9uEh91c2Vycy97dXNlcn0vc2Vzc2lvbnMve3Nlc3Npb259GgRuYW1lIkAKE0xpc3RTZXNzaW9uc1JlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyIj8KFExpc3RTZXNzaW9uc1Jlc3BvbnNlEicKCHNlc3Npb25zGAEgAygLMhUubWVtb3MuYXBpLnYxLlNlc3Npb24iKQoUUmV2b2tlU2Vzc2lvblJlcXVlc3QSEQoEbmFtZRgBIAEoCUID4EECIqoBCgtVc2VyV2ViaG9vaxIMCgRuYW1lGAEgASgJEgsKA3VybBgCIAEoCRIUCgxkaXNwbGF5X25hbWUYAyABKAkSNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSNAoLdXBkYXRlX3RpbWUYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMiLgoXTGlzdFVzZXJXZWJob29rc1JlcXVlc3QSEwoGcGFyZW50GAEgASgJQgPgQQIiRwoYTGlzdFVzZXJXZWJob29rc1Jlc3BvbnNlEisKCHdlYmhvb2tzGAEgAygLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rImAKGENyZWF0ZVVzZXJXZWJob29rUmVxdWVzdBITCgZwYXJlbnQYASABKAlCA+BBAhIvCgd3ZWJob29rGAIgASgLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rQgPgQQIifAoYVXBkYXRlVXNlcldlYmhvb2tSZXF1ZXN0Ei8KB3dlYmhvb2sYASABKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2tCA+BBAhIvCgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2siLQoYRGVsZXRlVXNlcldlYmhvb2tSZXF1ZXN0EhEKBG5hbWUYASABKAlCA+BBAiKKBAoQVXNlck5vdGlmaWNhdGlvbhIUCgRuYW1lGAEgASgJQgbgQQPgQQgSKQoGc2VuZGVyGAIgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEjoKBnN0YXR1cxgDIAEoDjIlLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uLlN0YXR1c0ID4EEBEjQKC2NyZWF0ZV90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDEjYKBHR5cGUYBSABKA4yIy5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbi5UeXBlQgPgQQMSHQoLYWN0aXZpdHlfaWQYBiABKAVCA+BBAUgAiAEBIjoKBlN0YXR1cxIWChJTVEFUVVNfVU5TUEVDSUZJRUQQABIKCgZVTlJFQUQQARIMCghBUkNISVZFRBACIi4KBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEhAKDE1FTU9fQ09NTUVOVBABOnDqQW0KHW1lbW9zLmFwaS52MS9Vc2VyTm90aWZpY2F0aW9uEil1c2Vycy97dXNlcn0vbm90aWZpY2F0aW9ucy97bm90aWZpY2F0aW9ufRoEbmFtZSoNbm90aWZpY2F0aW9uczIMbm90aWZpY2F0aW9uQg4KDF9hY3Rpdml0eV9pZCKPAQocTGlzdFVzZXJOb3RpZmljYXRpb25zUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBEhMKBmZpbHRlchgEIAEoCUID4EEBIm8KHUxpc3RVc2VyTm90aWZpY2F0aW9uc1Jlc3BvbnNlEjUKDW5vdGlmaWNhdGlvbnMYASADKAsyHi5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbhIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkikAEKHVVwZGF0ZVVzZXJOb3RpZmljYXRpb25SZXF1ZXN0EjkKDG5vdGlmaWNhdGlvbhgBIAEoCzIeLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQIiVAodRGVsZXRlVXNlck5vdGlmaWNhdGlvblJlcXVlc3QSMwoEbmFtZRgBIAEoCUIl4EEC+kEfCh1tZW1vcy5hcGkudjEvVXNlck5vdGlmaWNhdGlvbjKOGQoLVXNlclNlcnZpY2USYwoJTGlzdFVzZXJzEh4ubWVtb3MuYXBpLnYxLkxpc3RVc2Vyc1JlcXVlc3QaHy5tZW1vcy5hcGkudjEuTGlzdFVzZXJzUmVzcG9uc2UiFYLT5JMCDxINL2FwaS92MS91c2VycxJiCgdHZXRVc2VyEhwubWVtb3MuYXBpLnYxLkdldFVzZXJSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLlVzZXIiJdpBBG5hbWWC0+STAhgSFi9hcGkvdjEve25hbWU9dXNlcnMvKn0SZQoKQ3JlYXRlVXNlchIfLm1lbW9zLmFwaS52MS5DcmVhdGVVc2VyUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5Vc2VyIiLaQQR1c2VygtPkkwIVOgR1c2VyIg0vYXBpL3YxL3VzZXJzEn8KClVwZGF0ZVVzZXISHy5tZW1vcy5hcGkudjEuVXBkYXRlVXNlclJlcXVlc3QaEi5tZW1vcy5hcGkudjEuVXNlciI82kEQdXNlcix1cGRhdGVfbWFza4LT5JMCIzoEdXNlcjIbL2FwaS92MS97dXNlci5uYW1lPXVzZXJzLyp9EmwKCkRlbGV0ZVVzZXISHy5tZW1vcy5hcGkudjEuRGVsZXRlVXNlclJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiJdpBBG5hbWWC0+STAhgqFi9hcGkvdjEve25hbWU9dXNlcnMvKn0SfgoQTGlzdEFsbFVzZXJTdGF0cxIlLm1lbW9zLmFwaS52MS5MaXN0QWxsVXNlclN0YXRzUmVxdWVzdBomLm1lbW9zLmFwaS52MS5MaXN0QWxsVXNlclN0YXRzUmVzcG9uc2UiG4LT5JMCFRITL2FwaS92MS91c2VyczpzdGF0cxJ6CgxHZXRVc2VyU3RhdHMSIS5tZW1vcy5hcGkudjEuR2V0VXNlclN0YXRzUmVxdWVzdBoXLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMiLtpBBG5hbWWC0+STAiESHy9hcGkvdjEve25hbWU9dXNlcnMvKn06Z2V0U3RhdHMSggEKDkdldFVzZXJTZXR0aW5nEiMubWVtb3MuYXBpLnYxLkdldFVzZXJTZXR0aW5nUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZyIw2kEEbmFtZYLT5JMCIxIhL2FwaS92MS97bmFtZT11c2Vycy8qL3NldHRpbmdzLyp9EqgBChFVcGRhdGVVc2VyU2V0dGluZxImLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyU2V0dGluZ1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmciUNpBE3NldHRpbmcsdXBkYXRlX21hc2uC0+STAjQ6B3NldHRpbmcyKS9hcGkvdjEve3NldHRpbmcubmFtZT11c2Vycy8qL3NldHRpbmdzLyp9EpUBChBMaXN0VXNlclNldHRpbmdzEiUubWVtb3MuYXBpLnYxLkxpc3RVc2VyU2V0dGluZ3NSZXF1ZXN0GiYubWVtb3MuYXBpLnYxLkxpc3RVc2VyU2V0dGluZ3NSZXNwb25zZSIy2kEGcGFyZW50gtPkkwIjEiEvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vc2V0dGluZ3MSuQEKGExpc3RQZXJzb25hbEFjY2Vzc1Rva2VucxItLm1lbW9zLmFwaS52MS5MaXN0UGVyc29uYWxBY2Nlc3NUb2tlbnNSZXF1ZXN0Gi4ubWVtb3MuYXBpLnYxLkxpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1Jlc3BvbnNlIj7aQQZwYXJlbnSC0+STAi8SLS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS9wZXJzb25hbEFjY2Vzc1Rva2VucxK2AQoZQ3JlYXRlUGVyc29uYWxBY2Nlc3NUb2tlbhIuLm1lbW9zLmFwaS52MS5DcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVxdWVzdBovLm1lbW9zLmFwaS52MS5DcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVzcG9uc2UiOILT5JMCMjoBKiItL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3BlcnNvbmFsQWNjZXNzVG9rZW5zEqEBChlEZWxldGVQZXJzb25hbEFjY2Vzc1Rva2VuEi4ubWVtb3MuYXBpLnYxLkRlbGV0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjzaQQRuYW1lgtPkkwIvKi0vYXBpL3YxL3tuYW1lPXVzZXJzLyovcGVyc29uYWxBY2Nlc3NUb2tlbnMvKn0SiQEKDExpc3RTZXNzaW9ucxIhLm1lbW9zLmFwaS52MS5MaXN0U2Vzc2lvbnNSZXF1ZXN0GiIubWVtb3MuYXBpLnYxLkxpc3RTZXNzaW9uc1Jlc3BvbnNlIjLaQQZwYXJlbnSC0+STAiMSIS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS9zZXNzaW9ucxJ9Cg1SZXZva2VTZXNzaW9uEiIubWVtb3MuYXBpLnYxLlJldm9rZVNlc3Npb25SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjDaQQRuYW1lgtPkkwIjKiEvYXBpL3YxL3tuYW1lPXVzZXJzLyovc2Vzc2lvbnMvKn0SlQEKEExpc3RVc2VyV2ViaG9va3MSJS5tZW1vcy5hcGkudjEuTGlzdFVzZXJXZWJob29rc1JlcXVlc3QaJi5tZW1vcy5hcGkudjEuTGlzdFVzZXJXZWJob29rc1Jlc3BvbnNlIjLaQQZwYXJlbnSC0+STAiMSIS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS93ZWJob29rcxKbAQoRQ3JlYXRlVXNlcldlYmhvb2sSJi5tZW1vcy5hcGkudjEuQ3JlYXRlVXNlcldlYmhvb2tSZXF1ZXN0GhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rIkPaQQ5wYXJlbnQsd2ViaG9va4LT5JMCLDoHd2ViaG9vayIhL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3dlYmhvb2tzEqgBChFVcGRhdGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyV2ViaG9va1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siUNpBE3dlYmhvb2ssdXBkYXRlX21hc2uC0+STAjQ6B3dlYmhvb2syKS9hcGkvdjEve3dlYmhvb2submFtZT11c2Vycy8qL3dlYmhvb2tzLyp9EoUBChFEZWxldGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyV2ViaG9va1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiMNpBBG5hbWWC0+STAiMqIS9hcGkvdjEve25hbWU9dXNlcnMvKi93ZWJob29rcy8qfRKpAQoVTGlzdFVzZXJOb3RpZmljYXRpb25zEioubWVtb3MuYXBpLnYxLkxpc3RVc2VyTm90aWZpY2F0aW9uc1JlcXVlc3QaKy5tZW1vcy5hcGkudjEuTGlzdFVzZXJOb3RpZmljYXRpb25zUmVzcG9uc2UiN9pBBnBhcmVudILT5JMCKBImL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L25vdGlmaWNhdGlvbnMSywEKFlVwZGF0ZVVzZXJOb3RpZmljYXRpb24SKy5tZW1vcy5hcGkudjEuVXBkYXRlVXNlck5vdGlmaWNhdGlvblJlcXVlc3QaHi5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbiJk2kEYbm90aWZpY2F0aW9uLHVwZGF0ZV9tYXNrgtPkkwJDOgxub3RpZmljYXRpb24yMy9hcGkvdjEve25vdGlmaWNhdGlvbi5uYW1lPXVzZXJzLyovbm90aWZpY2F0aW9ucy8qfRKUAQoWRGVsZXRlVXNlck5vdGlmaWNhdGlvbhIrLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSI12kEEbmFtZYLT5JMCKComL2FwaS92MS97bmFtZT11c2Vycy8qL25vdGlmaWNhdGlvbnMvKn1CqAEKEGNvbS5tZW1vcy5hcGkudjFCEFVzZXJTZXJ2aWNlUHJvdG9QAVowZ2l0aHViLmNvbS91c2VtZW1vcy9tZW1vcy9wcm90by9nZW4vYXBpL3YxO2FwaXYxogIDTUFYqgIMTWVtb3MuQXBpLlYxygIMTWVtb3NcQXBpXFYx4gIYTWVtb3NcQXBpXFYxXEdQQk1ldGFkYXRh6gIOTWVtb3M6OkFwaTo6VjFiBnByb3RvMw", [file_api_v1_common, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp]); + fileDesc("ChlhcGkvdjEvdXNlcl9zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEi4AMKBFVzZXISEQoEbmFtZRgBIAEoCUID4EEIEioKBHJvbGUYAiABKA4yFy5tZW1vcy5hcGkudjEuVXNlci5Sb2xlQgPgQQISFQoIdXNlcm5hbWUYAyABKAlCA+BBAhISCgVlbWFpbBgEIAEoCUID4EEBEhkKDGRpc3BsYXlfbmFtZRgFIAEoCUID4EEBEhcKCmF2YXRhcl91cmwYBiABKAlCA+BBARIYCgtkZXNjcmlwdGlvbhgHIAEoCUID4EEBEhUKCHBhc3N3b3JkGAggASgJQgPgQQQSJwoFc3RhdGUYCSABKA4yEy5tZW1vcy5hcGkudjEuU3RhdGVCA+BBAhI0CgtjcmVhdGVfdGltZRgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAyI7CgRSb2xlEhQKEFJPTEVfVU5TUEVDSUZJRUQQABIICgRIT1NUEAESCQoFQURNSU4QAhIICgRVU0VSEAM6N+pBNAoRbWVtb3MuYXBpLnYxL1VzZXISDHVzZXJzL3t1c2VyfRoEbmFtZSoFdXNlcnMyBHVzZXIicwoQTGlzdFVzZXJzUmVxdWVzdBIWCglwYWdlX3NpemUYASABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAIgASgJQgPgQQESEwoGZmlsdGVyGAMgASgJQgPgQQESGQoMc2hvd19kZWxldGVkGAQgASgIQgPgQQEiYwoRTGlzdFVzZXJzUmVzcG9uc2USIQoFdXNlcnMYASADKAsyEi5tZW1vcy5hcGkudjEuVXNlchIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkSEgoKdG90YWxfc2l6ZRgDIAEoBSJtCg5HZXRVc2VyUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEjIKCXJlYWRfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBASKIAQoRQ3JlYXRlVXNlclJlcXVlc3QSKAoEdXNlchgBIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyQgbgQQLgQQQSFAoHdXNlcl9pZBgCIAEoCUID4EEBEhoKDXZhbGlkYXRlX29ubHkYAyABKAhCA+BBARIXCgpyZXF1ZXN0X2lkGAQgASgJQgPgQQEijAEKEVVwZGF0ZVVzZXJSZXF1ZXN0EiUKBHVzZXIYASABKAsyEi5tZW1vcy5hcGkudjEuVXNlckID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECEhoKDWFsbG93X21pc3NpbmcYAyABKAhCA+BBASJQChFEZWxldGVVc2VyUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhIKBWZvcmNlGAIgASgIQgPgQQEi2AMKCVVzZXJTdGF0cxIRCgRuYW1lGAEgASgJQgPgQQgSOwoXbWVtb19kaXNwbGF5X3RpbWVzdGFtcHMYAiADKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEj4KD21lbW9fdHlwZV9zdGF0cxgDIAEoCzIlLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMuTWVtb1R5cGVTdGF0cxI4Cgl0YWdfY291bnQYBCADKAsyJS5tZW1vcy5hcGkudjEuVXNlclN0YXRzLlRhZ0NvdW50RW50cnkSFAoMcGlubmVkX21lbW9zGAUgAygJEhgKEHRvdGFsX21lbW9fY291bnQYBiABKAUaLwoNVGFnQ291bnRFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAU6AjgBGl8KDU1lbW9UeXBlU3RhdHMSEgoKbGlua19jb3VudBgBIAEoBRISCgpjb2RlX2NvdW50GAIgASgFEhIKCnRvZG9fY291bnQYAyABKAUSEgoKdW5kb19jb3VudBgEIAEoBTo/6kE8ChZtZW1vcy5hcGkudjEvVXNlclN0YXRzEgx1c2Vycy97dXNlcn0qCXVzZXJTdGF0czIJdXNlclN0YXRzIj4KE0dldFVzZXJTdGF0c1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlciIZChdMaXN0QWxsVXNlclN0YXRzUmVxdWVzdCJCChhMaXN0QWxsVXNlclN0YXRzUmVzcG9uc2USJgoFc3RhdHMYASADKAsyFy5tZW1vcy5hcGkudjEuVXNlclN0YXRzIuADCgtVc2VyU2V0dGluZxIRCgRuYW1lGAEgASgJQgPgQQgSQwoPZ2VuZXJhbF9zZXR0aW5nGAIgASgLMigubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nLkdlbmVyYWxTZXR0aW5nSAASRQoQd2ViaG9va3Nfc2V0dGluZxgFIAEoCzIpLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZy5XZWJob29rc1NldHRpbmdIABpXCg5HZW5lcmFsU2V0dGluZxITCgZsb2NhbGUYASABKAlCA+BBARIcCg9tZW1vX3Zpc2liaWxpdHkYAyABKAlCA+BBARISCgV0aGVtZRgEIAEoCUID4EEBGj4KD1dlYmhvb2tzU2V0dGluZxIrCgh3ZWJob29rcxgBIAMoCzIZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9vayI1CgNLZXkSEwoPS0VZX1VOU1BFQ0lGSUVEEAASCwoHR0VORVJBTBABEgwKCFdFQkhPT0tTEAQ6WepBVgoYbWVtb3MuYXBpLnYxL1VzZXJTZXR0aW5nEh91c2Vycy97dXNlcn0vc2V0dGluZ3Mve3NldHRpbmd9Kgx1c2VyU2V0dGluZ3MyC3VzZXJTZXR0aW5nQgcKBXZhbHVlIkcKFUdldFVzZXJTZXR0aW5nUmVxdWVzdBIuCgRuYW1lGAEgASgJQiDgQQL6QRoKGG1lbW9zLmFwaS52MS9Vc2VyU2V0dGluZyKBAQoYVXBkYXRlVXNlclNldHRpbmdSZXF1ZXN0Ei8KB3NldHRpbmcYASABKAsyGS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmdCA+BBAhI0Cgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBAiJ1ChdMaXN0VXNlclNldHRpbmdzUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBInQKGExpc3RVc2VyU2V0dGluZ3NSZXNwb25zZRIrCghzZXR0aW5ncxgBIAMoCzIZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZxIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkSEgoKdG90YWxfc2l6ZRgDIAEoBSLyAgoTUGVyc29uYWxBY2Nlc3NUb2tlbhIRCgRuYW1lGAEgASgJQgPgQQgSGAoLZGVzY3JpcHRpb24YAiABKAlCA+BBARIzCgpjcmVhdGVkX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDEjMKCmV4cGlyZXNfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQESNQoMbGFzdF91c2VkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDOowB6kGIAQogbWVtb3MuYXBpLnYxL1BlcnNvbmFsQWNjZXNzVG9rZW4SOXVzZXJzL3t1c2VyfS9wZXJzb25hbEFjY2Vzc1Rva2Vucy97cGVyc29uYWxfYWNjZXNzX3Rva2VufSoUcGVyc29uYWxBY2Nlc3NUb2tlbnMyE3BlcnNvbmFsQWNjZXNzVG9rZW4ifQofTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBIpIBCiBMaXN0UGVyc29uYWxBY2Nlc3NUb2tlbnNSZXNwb25zZRJBChZwZXJzb25hbF9hY2Nlc3NfdG9rZW5zGAEgAygLMiEubWVtb3MuYXBpLnYxLlBlcnNvbmFsQWNjZXNzVG9rZW4SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJEhIKCnRvdGFsX3NpemUYAyABKAUihQEKIENyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIYCgtkZXNjcmlwdGlvbhgCIAEoCUID4EEBEhwKD2V4cGlyZXNfaW5fZGF5cxgDIAEoBUID4EEBInQKIUNyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXNwb25zZRJAChVwZXJzb25hbF9hY2Nlc3NfdG9rZW4YASABKAsyIS5tZW1vcy5hcGkudjEuUGVyc29uYWxBY2Nlc3NUb2tlbhINCgV0b2tlbhgCIAEoCSJaCiBEZWxldGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVxdWVzdBI2CgRuYW1lGAEgASgJQijgQQL6QSIKIG1lbW9zLmFwaS52MS9QZXJzb25hbEFjY2Vzc1Rva2VuIqoBCgtVc2VyV2ViaG9vaxIMCgRuYW1lGAEgASgJEgsKA3VybBgCIAEoCRIUCgxkaXNwbGF5X25hbWUYAyABKAkSNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSNAoLdXBkYXRlX3RpbWUYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMiLgoXTGlzdFVzZXJXZWJob29rc1JlcXVlc3QSEwoGcGFyZW50GAEgASgJQgPgQQIiRwoYTGlzdFVzZXJXZWJob29rc1Jlc3BvbnNlEisKCHdlYmhvb2tzGAEgAygLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rImAKGENyZWF0ZVVzZXJXZWJob29rUmVxdWVzdBITCgZwYXJlbnQYASABKAlCA+BBAhIvCgd3ZWJob29rGAIgASgLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rQgPgQQIifAoYVXBkYXRlVXNlcldlYmhvb2tSZXF1ZXN0Ei8KB3dlYmhvb2sYASABKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2tCA+BBAhIvCgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2siLQoYRGVsZXRlVXNlcldlYmhvb2tSZXF1ZXN0EhEKBG5hbWUYASABKAlCA+BBAiKKBAoQVXNlck5vdGlmaWNhdGlvbhIUCgRuYW1lGAEgASgJQgbgQQPgQQgSKQoGc2VuZGVyGAIgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEjoKBnN0YXR1cxgDIAEoDjIlLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uLlN0YXR1c0ID4EEBEjQKC2NyZWF0ZV90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDEjYKBHR5cGUYBSABKA4yIy5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbi5UeXBlQgPgQQMSHQoLYWN0aXZpdHlfaWQYBiABKAVCA+BBAUgAiAEBIjoKBlN0YXR1cxIWChJTVEFUVVNfVU5TUEVDSUZJRUQQABIKCgZVTlJFQUQQARIMCghBUkNISVZFRBACIi4KBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEhAKDE1FTU9fQ09NTUVOVBABOnDqQW0KHW1lbW9zLmFwaS52MS9Vc2VyTm90aWZpY2F0aW9uEil1c2Vycy97dXNlcn0vbm90aWZpY2F0aW9ucy97bm90aWZpY2F0aW9ufRoEbmFtZSoNbm90aWZpY2F0aW9uczIMbm90aWZpY2F0aW9uQg4KDF9hY3Rpdml0eV9pZCKPAQocTGlzdFVzZXJOb3RpZmljYXRpb25zUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBEhMKBmZpbHRlchgEIAEoCUID4EEBIm8KHUxpc3RVc2VyTm90aWZpY2F0aW9uc1Jlc3BvbnNlEjUKDW5vdGlmaWNhdGlvbnMYASADKAsyHi5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbhIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkikAEKHVVwZGF0ZVVzZXJOb3RpZmljYXRpb25SZXF1ZXN0EjkKDG5vdGlmaWNhdGlvbhgBIAEoCzIeLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQIiVAodRGVsZXRlVXNlck5vdGlmaWNhdGlvblJlcXVlc3QSMwoEbmFtZRgBIAEoCUIl4EEC+kEfCh1tZW1vcy5hcGkudjEvVXNlck5vdGlmaWNhdGlvbjKDFwoLVXNlclNlcnZpY2USYwoJTGlzdFVzZXJzEh4ubWVtb3MuYXBpLnYxLkxpc3RVc2Vyc1JlcXVlc3QaHy5tZW1vcy5hcGkudjEuTGlzdFVzZXJzUmVzcG9uc2UiFYLT5JMCDxINL2FwaS92MS91c2VycxJiCgdHZXRVc2VyEhwubWVtb3MuYXBpLnYxLkdldFVzZXJSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLlVzZXIiJdpBBG5hbWWC0+STAhgSFi9hcGkvdjEve25hbWU9dXNlcnMvKn0SZQoKQ3JlYXRlVXNlchIfLm1lbW9zLmFwaS52MS5DcmVhdGVVc2VyUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5Vc2VyIiLaQQR1c2VygtPkkwIVOgR1c2VyIg0vYXBpL3YxL3VzZXJzEn8KClVwZGF0ZVVzZXISHy5tZW1vcy5hcGkudjEuVXBkYXRlVXNlclJlcXVlc3QaEi5tZW1vcy5hcGkudjEuVXNlciI82kEQdXNlcix1cGRhdGVfbWFza4LT5JMCIzoEdXNlcjIbL2FwaS92MS97dXNlci5uYW1lPXVzZXJzLyp9EmwKCkRlbGV0ZVVzZXISHy5tZW1vcy5hcGkudjEuRGVsZXRlVXNlclJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiJdpBBG5hbWWC0+STAhgqFi9hcGkvdjEve25hbWU9dXNlcnMvKn0SfgoQTGlzdEFsbFVzZXJTdGF0cxIlLm1lbW9zLmFwaS52MS5MaXN0QWxsVXNlclN0YXRzUmVxdWVzdBomLm1lbW9zLmFwaS52MS5MaXN0QWxsVXNlclN0YXRzUmVzcG9uc2UiG4LT5JMCFRITL2FwaS92MS91c2VyczpzdGF0cxJ6CgxHZXRVc2VyU3RhdHMSIS5tZW1vcy5hcGkudjEuR2V0VXNlclN0YXRzUmVxdWVzdBoXLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMiLtpBBG5hbWWC0+STAiESHy9hcGkvdjEve25hbWU9dXNlcnMvKn06Z2V0U3RhdHMSggEKDkdldFVzZXJTZXR0aW5nEiMubWVtb3MuYXBpLnYxLkdldFVzZXJTZXR0aW5nUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZyIw2kEEbmFtZYLT5JMCIxIhL2FwaS92MS97bmFtZT11c2Vycy8qL3NldHRpbmdzLyp9EqgBChFVcGRhdGVVc2VyU2V0dGluZxImLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyU2V0dGluZ1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmciUNpBE3NldHRpbmcsdXBkYXRlX21hc2uC0+STAjQ6B3NldHRpbmcyKS9hcGkvdjEve3NldHRpbmcubmFtZT11c2Vycy8qL3NldHRpbmdzLyp9EpUBChBMaXN0VXNlclNldHRpbmdzEiUubWVtb3MuYXBpLnYxLkxpc3RVc2VyU2V0dGluZ3NSZXF1ZXN0GiYubWVtb3MuYXBpLnYxLkxpc3RVc2VyU2V0dGluZ3NSZXNwb25zZSIy2kEGcGFyZW50gtPkkwIjEiEvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vc2V0dGluZ3MSuQEKGExpc3RQZXJzb25hbEFjY2Vzc1Rva2VucxItLm1lbW9zLmFwaS52MS5MaXN0UGVyc29uYWxBY2Nlc3NUb2tlbnNSZXF1ZXN0Gi4ubWVtb3MuYXBpLnYxLkxpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1Jlc3BvbnNlIj7aQQZwYXJlbnSC0+STAi8SLS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS9wZXJzb25hbEFjY2Vzc1Rva2VucxK2AQoZQ3JlYXRlUGVyc29uYWxBY2Nlc3NUb2tlbhIuLm1lbW9zLmFwaS52MS5DcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVxdWVzdBovLm1lbW9zLmFwaS52MS5DcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVzcG9uc2UiOILT5JMCMjoBKiItL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3BlcnNvbmFsQWNjZXNzVG9rZW5zEqEBChlEZWxldGVQZXJzb25hbEFjY2Vzc1Rva2VuEi4ubWVtb3MuYXBpLnYxLkRlbGV0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjzaQQRuYW1lgtPkkwIvKi0vYXBpL3YxL3tuYW1lPXVzZXJzLyovcGVyc29uYWxBY2Nlc3NUb2tlbnMvKn0SlQEKEExpc3RVc2VyV2ViaG9va3MSJS5tZW1vcy5hcGkudjEuTGlzdFVzZXJXZWJob29rc1JlcXVlc3QaJi5tZW1vcy5hcGkudjEuTGlzdFVzZXJXZWJob29rc1Jlc3BvbnNlIjLaQQZwYXJlbnSC0+STAiMSIS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS93ZWJob29rcxKbAQoRQ3JlYXRlVXNlcldlYmhvb2sSJi5tZW1vcy5hcGkudjEuQ3JlYXRlVXNlcldlYmhvb2tSZXF1ZXN0GhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rIkPaQQ5wYXJlbnQsd2ViaG9va4LT5JMCLDoHd2ViaG9vayIhL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3dlYmhvb2tzEqgBChFVcGRhdGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyV2ViaG9va1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siUNpBE3dlYmhvb2ssdXBkYXRlX21hc2uC0+STAjQ6B3dlYmhvb2syKS9hcGkvdjEve3dlYmhvb2submFtZT11c2Vycy8qL3dlYmhvb2tzLyp9EoUBChFEZWxldGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyV2ViaG9va1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiMNpBBG5hbWWC0+STAiMqIS9hcGkvdjEve25hbWU9dXNlcnMvKi93ZWJob29rcy8qfRKpAQoVTGlzdFVzZXJOb3RpZmljYXRpb25zEioubWVtb3MuYXBpLnYxLkxpc3RVc2VyTm90aWZpY2F0aW9uc1JlcXVlc3QaKy5tZW1vcy5hcGkudjEuTGlzdFVzZXJOb3RpZmljYXRpb25zUmVzcG9uc2UiN9pBBnBhcmVudILT5JMCKBImL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L25vdGlmaWNhdGlvbnMSywEKFlVwZGF0ZVVzZXJOb3RpZmljYXRpb24SKy5tZW1vcy5hcGkudjEuVXBkYXRlVXNlck5vdGlmaWNhdGlvblJlcXVlc3QaHi5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbiJk2kEYbm90aWZpY2F0aW9uLHVwZGF0ZV9tYXNrgtPkkwJDOgxub3RpZmljYXRpb24yMy9hcGkvdjEve25vdGlmaWNhdGlvbi5uYW1lPXVzZXJzLyovbm90aWZpY2F0aW9ucy8qfRKUAQoWRGVsZXRlVXNlck5vdGlmaWNhdGlvbhIrLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSI12kEEbmFtZYLT5JMCKComL2FwaS92MS97bmFtZT11c2Vycy8qL25vdGlmaWNhdGlvbnMvKn1CqAEKEGNvbS5tZW1vcy5hcGkudjFCEFVzZXJTZXJ2aWNlUHJvdG9QAVowZ2l0aHViLmNvbS91c2VtZW1vcy9tZW1vcy9wcm90by9nZW4vYXBpL3YxO2FwaXYxogIDTUFYqgIMTWVtb3MuQXBpLlYxygIMTWVtb3NcQXBpXFYx4gIYTWVtb3NcQXBpXFYxXEdQQk1ldGFkYXRh6gIOTWVtb3M6OkFwaTo6VjFiBnByb3RvMw", [file_api_v1_common, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp]); /** * @generated from message memos.api.v1.User @@ -535,18 +535,6 @@ export type UserSetting = Message<"memos.api.v1.UserSetting"> & { */ value: UserSetting_GeneralSetting; case: "generalSetting"; - } | { - /** - * @generated from field: memos.api.v1.UserSetting.SessionsSetting sessions_setting = 3; - */ - value: UserSetting_SessionsSetting; - case: "sessionsSetting"; - } | { - /** - * @generated from field: memos.api.v1.UserSetting.AccessTokensSetting access_tokens_setting = 4; - */ - value: UserSetting_AccessTokensSetting; - case: "accessTokensSetting"; } | { /** * @generated from field: memos.api.v1.UserSetting.WebhooksSetting webhooks_setting = 5; @@ -600,48 +588,6 @@ export type UserSetting_GeneralSetting = Message<"memos.api.v1.UserSetting.Gener export const UserSetting_GeneralSettingSchema: GenMessage = /*@__PURE__*/ messageDesc(file_api_v1_user_service, 11, 0); -/** - * User authentication sessions configuration. - * - * @generated from message memos.api.v1.UserSetting.SessionsSetting - */ -export type UserSetting_SessionsSetting = Message<"memos.api.v1.UserSetting.SessionsSetting"> & { - /** - * List of active login sessions. - * - * @generated from field: repeated memos.api.v1.Session sessions = 1; - */ - sessions: Session[]; -}; - -/** - * Describes the message memos.api.v1.UserSetting.SessionsSetting. - * Use `create(UserSetting_SessionsSettingSchema)` to create a new message. - */ -export const UserSetting_SessionsSettingSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 11, 1); - -/** - * Personal access tokens configuration. - * - * @generated from message memos.api.v1.UserSetting.AccessTokensSetting - */ -export type UserSetting_AccessTokensSetting = Message<"memos.api.v1.UserSetting.AccessTokensSetting"> & { - /** - * List of personal access tokens (PATs). - * - * @generated from field: repeated memos.api.v1.PersonalAccessToken personal_access_tokens = 1; - */ - personalAccessTokens: PersonalAccessToken[]; -}; - -/** - * Describes the message memos.api.v1.UserSetting.AccessTokensSetting. - * Use `create(UserSetting_AccessTokensSettingSchema)` to create a new message. - */ -export const UserSetting_AccessTokensSettingSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 11, 2); - /** * User webhooks configuration. * @@ -661,7 +607,7 @@ export type UserSetting_WebhooksSetting = Message<"memos.api.v1.UserSetting.Webh * Use `create(UserSetting_WebhooksSettingSchema)` to create a new message. */ export const UserSetting_WebhooksSettingSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 11, 3); + messageDesc(file_api_v1_user_service, 11, 1); /** * Enumeration of user setting keys. @@ -681,20 +627,6 @@ export enum UserSetting_Key { */ GENERAL = 1, - /** - * SESSIONS is the key for user login sessions (refresh tokens). - * - * @generated from enum value: SESSIONS = 2; - */ - SESSIONS = 2, - - /** - * ACCESS_TOKENS is the key for Personal Access Tokens (PATs). - * - * @generated from enum value: ACCESS_TOKENS = 3; - */ - ACCESS_TOKENS = 3, - /** * WEBHOOKS is the key for user webhooks. * @@ -1030,164 +962,6 @@ export type DeletePersonalAccessTokenRequest = Message<"memos.api.v1.DeletePerso export const DeletePersonalAccessTokenRequestSchema: GenMessage = /*@__PURE__*/ messageDesc(file_api_v1_user_service, 21); -/** - * Session represents a user's login session on a specific device/browser. - * Sessions are backed by refresh tokens with sliding expiration. - * - * @generated from message memos.api.v1.Session - */ -export type Session = Message<"memos.api.v1.Session"> & { - /** - * The resource name of the session. - * Format: users/{user}/sessions/{session} - * - * @generated from field: string name = 1; - */ - name: string; - - /** - * The session ID. - * - * @generated from field: string session_id = 2; - */ - sessionId: string; - - /** - * The timestamp when the session was created. - * - * @generated from field: google.protobuf.Timestamp create_time = 3; - */ - createTime?: Timestamp; - - /** - * The timestamp when the session was last accessed. - * Used for sliding expiration calculation (last_accessed_time + 2 weeks). - * - * @generated from field: google.protobuf.Timestamp last_accessed_time = 4; - */ - lastAccessedTime?: Timestamp; - - /** - * Client information associated with this session. - * - * @generated from field: memos.api.v1.Session.ClientInfo client_info = 5; - */ - clientInfo?: Session_ClientInfo; -}; - -/** - * Describes the message memos.api.v1.Session. - * Use `create(SessionSchema)` to create a new message. - */ -export const SessionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 22); - -/** - * @generated from message memos.api.v1.Session.ClientInfo - */ -export type Session_ClientInfo = Message<"memos.api.v1.Session.ClientInfo"> & { - /** - * User agent string of the client. - * - * @generated from field: string user_agent = 1; - */ - userAgent: string; - - /** - * IP address of the client. - * - * @generated from field: string ip_address = 2; - */ - ipAddress: string; - - /** - * Optional. Device type (e.g., "mobile", "desktop", "tablet"). - * - * @generated from field: string device_type = 3; - */ - deviceType: string; - - /** - * Optional. Operating system (e.g., "iOS 17.0", "Windows 11"). - * - * @generated from field: string os = 4; - */ - os: string; - - /** - * Optional. Browser name and version (e.g., "Chrome 119.0"). - * - * @generated from field: string browser = 5; - */ - browser: string; -}; - -/** - * Describes the message memos.api.v1.Session.ClientInfo. - * Use `create(Session_ClientInfoSchema)` to create a new message. - */ -export const Session_ClientInfoSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 22, 0); - -/** - * @generated from message memos.api.v1.ListSessionsRequest - */ -export type ListSessionsRequest = Message<"memos.api.v1.ListSessionsRequest"> & { - /** - * Required. The resource name of the parent. - * Format: users/{user} - * - * @generated from field: string parent = 1; - */ - parent: string; -}; - -/** - * Describes the message memos.api.v1.ListSessionsRequest. - * Use `create(ListSessionsRequestSchema)` to create a new message. - */ -export const ListSessionsRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 23); - -/** - * @generated from message memos.api.v1.ListSessionsResponse - */ -export type ListSessionsResponse = Message<"memos.api.v1.ListSessionsResponse"> & { - /** - * The list of sessions. - * - * @generated from field: repeated memos.api.v1.Session sessions = 1; - */ - sessions: Session[]; -}; - -/** - * Describes the message memos.api.v1.ListSessionsResponse. - * Use `create(ListSessionsResponseSchema)` to create a new message. - */ -export const ListSessionsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 24); - -/** - * @generated from message memos.api.v1.RevokeSessionRequest - */ -export type RevokeSessionRequest = Message<"memos.api.v1.RevokeSessionRequest"> & { - /** - * The name of the session to revoke. - * Format: users/{user}/sessions/{session} - * - * @generated from field: string name = 1; - */ - name: string; -}; - -/** - * Describes the message memos.api.v1.RevokeSessionRequest. - * Use `create(RevokeSessionRequestSchema)` to create a new message. - */ -export const RevokeSessionRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 25); - /** * UserWebhook represents a webhook owned by a user. * @@ -1236,7 +1010,7 @@ export type UserWebhook = Message<"memos.api.v1.UserWebhook"> & { * Use `create(UserWebhookSchema)` to create a new message. */ export const UserWebhookSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 26); + messageDesc(file_api_v1_user_service, 22); /** * @generated from message memos.api.v1.ListUserWebhooksRequest @@ -1256,7 +1030,7 @@ export type ListUserWebhooksRequest = Message<"memos.api.v1.ListUserWebhooksRequ * Use `create(ListUserWebhooksRequestSchema)` to create a new message. */ export const ListUserWebhooksRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 27); + messageDesc(file_api_v1_user_service, 23); /** * @generated from message memos.api.v1.ListUserWebhooksResponse @@ -1275,7 +1049,7 @@ export type ListUserWebhooksResponse = Message<"memos.api.v1.ListUserWebhooksRes * Use `create(ListUserWebhooksResponseSchema)` to create a new message. */ export const ListUserWebhooksResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 28); + messageDesc(file_api_v1_user_service, 24); /** * @generated from message memos.api.v1.CreateUserWebhookRequest @@ -1302,7 +1076,7 @@ export type CreateUserWebhookRequest = Message<"memos.api.v1.CreateUserWebhookRe * Use `create(CreateUserWebhookRequestSchema)` to create a new message. */ export const CreateUserWebhookRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 29); + messageDesc(file_api_v1_user_service, 25); /** * @generated from message memos.api.v1.UpdateUserWebhookRequest @@ -1328,7 +1102,7 @@ export type UpdateUserWebhookRequest = Message<"memos.api.v1.UpdateUserWebhookRe * Use `create(UpdateUserWebhookRequestSchema)` to create a new message. */ export const UpdateUserWebhookRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 30); + messageDesc(file_api_v1_user_service, 26); /** * @generated from message memos.api.v1.DeleteUserWebhookRequest @@ -1348,7 +1122,7 @@ export type DeleteUserWebhookRequest = Message<"memos.api.v1.DeleteUserWebhookRe * Use `create(DeleteUserWebhookRequestSchema)` to create a new message. */ export const DeleteUserWebhookRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 31); + messageDesc(file_api_v1_user_service, 27); /** * @generated from message memos.api.v1.UserNotification @@ -1404,7 +1178,7 @@ export type UserNotification = Message<"memos.api.v1.UserNotification"> & { * Use `create(UserNotificationSchema)` to create a new message. */ export const UserNotificationSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 32); + messageDesc(file_api_v1_user_service, 28); /** * @generated from enum memos.api.v1.UserNotification.Status @@ -1430,7 +1204,7 @@ export enum UserNotification_Status { * Describes the enum memos.api.v1.UserNotification.Status. */ export const UserNotification_StatusSchema: GenEnum = /*@__PURE__*/ - enumDesc(file_api_v1_user_service, 32, 0); + enumDesc(file_api_v1_user_service, 28, 0); /** * @generated from enum memos.api.v1.UserNotification.Type @@ -1451,7 +1225,7 @@ export enum UserNotification_Type { * Describes the enum memos.api.v1.UserNotification.Type. */ export const UserNotification_TypeSchema: GenEnum = /*@__PURE__*/ - enumDesc(file_api_v1_user_service, 32, 1); + enumDesc(file_api_v1_user_service, 28, 1); /** * @generated from message memos.api.v1.ListUserNotificationsRequest @@ -1486,7 +1260,7 @@ export type ListUserNotificationsRequest = Message<"memos.api.v1.ListUserNotific * Use `create(ListUserNotificationsRequestSchema)` to create a new message. */ export const ListUserNotificationsRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 33); + messageDesc(file_api_v1_user_service, 29); /** * @generated from message memos.api.v1.ListUserNotificationsResponse @@ -1508,7 +1282,7 @@ export type ListUserNotificationsResponse = Message<"memos.api.v1.ListUserNotifi * Use `create(ListUserNotificationsResponseSchema)` to create a new message. */ export const ListUserNotificationsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 34); + messageDesc(file_api_v1_user_service, 30); /** * @generated from message memos.api.v1.UpdateUserNotificationRequest @@ -1530,7 +1304,7 @@ export type UpdateUserNotificationRequest = Message<"memos.api.v1.UpdateUserNoti * Use `create(UpdateUserNotificationRequestSchema)` to create a new message. */ export const UpdateUserNotificationRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 35); + messageDesc(file_api_v1_user_service, 31); /** * @generated from message memos.api.v1.DeleteUserNotificationRequest @@ -1549,7 +1323,7 @@ export type DeleteUserNotificationRequest = Message<"memos.api.v1.DeleteUserNoti * Use `create(DeleteUserNotificationRequestSchema)` to create a new message. */ export const DeleteUserNotificationRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 36); + messageDesc(file_api_v1_user_service, 32); /** * @generated from service memos.api.v1.UserService @@ -1690,29 +1464,6 @@ export const UserService: GenService<{ input: typeof DeletePersonalAccessTokenRequestSchema; output: typeof EmptySchema; }, - /** - * ListSessions returns a list of active login sessions for a user. - * Each session represents a browser/device where the user is logged in. - * Sessions are backed by refresh tokens with sliding expiration. - * - * @generated from rpc memos.api.v1.UserService.ListSessions - */ - listSessions: { - methodKind: "unary"; - input: typeof ListSessionsRequestSchema; - output: typeof ListSessionsResponseSchema; - }, - /** - * RevokeSession revokes a specific login session. - * This invalidates the refresh token, forcing re-authentication on that device. - * - * @generated from rpc memos.api.v1.UserService.RevokeSession - */ - revokeSession: { - methodKind: "unary"; - input: typeof RevokeSessionRequestSchema; - output: typeof EmptySchema; - }, /** * ListUserWebhooks returns a list of webhooks for a user. *