From f9f239d4d3e1c6867a7b7a45378541f5b3a71837 Mon Sep 17 00:00:00 2001 From: =AhmedAshraf <=ahmedashrafelgendy25@gmail.com> Date: Mon, 23 Mar 2026 06:09:06 +0200 Subject: [PATCH] chore: format proto files --- proto/api/v1/attachment_service.proto | 300 +++--- proto/api/v1/auth_service.proto | 230 ++--- proto/api/v1/common.proto | 46 +- proto/api/v1/idp_service.proto | 294 +++--- proto/api/v1/instance_service.proto | 440 ++++---- proto/api/v1/memo_service.proto | 1194 ++++++++++----------- proto/api/v1/shortcut_service.proto | 248 ++--- proto/api/v1/user_service.proto | 1368 ++++++++++++------------- proto/store/attachment.proto | 66 +- proto/store/idp.proto | 84 +- proto/store/inbox.proto | 48 +- proto/store/instance_setting.proto | 282 ++--- proto/store/memo.proto | 58 +- proto/store/user_setting.proto | 226 ++-- 14 files changed, 2442 insertions(+), 2442 deletions(-) diff --git a/proto/api/v1/attachment_service.proto b/proto/api/v1/attachment_service.proto index c2357b601..da6db3116 100644 --- a/proto/api/v1/attachment_service.proto +++ b/proto/api/v1/attachment_service.proto @@ -1,150 +1,150 @@ -syntax = "proto3"; - -package memos.api.v1; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/field_mask.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "gen/api/v1"; - -service AttachmentService { - // CreateAttachment creates a new attachment. - rpc CreateAttachment(CreateAttachmentRequest) returns (Attachment) { - option (google.api.http) = { - post: "/api/v1/attachments" - body: "attachment" - }; - option (google.api.method_signature) = "attachment"; - } - // ListAttachments lists all attachments. - rpc ListAttachments(ListAttachmentsRequest) returns (ListAttachmentsResponse) { - option (google.api.http) = {get: "/api/v1/attachments"}; - } - // GetAttachment returns an attachment by name. - rpc GetAttachment(GetAttachmentRequest) returns (Attachment) { - option (google.api.http) = {get: "/api/v1/{name=attachments/*}"}; - option (google.api.method_signature) = "name"; - } - // UpdateAttachment updates an attachment. - rpc UpdateAttachment(UpdateAttachmentRequest) returns (Attachment) { - option (google.api.http) = { - patch: "/api/v1/{attachment.name=attachments/*}" - body: "attachment" - }; - option (google.api.method_signature) = "attachment,update_mask"; - } - // DeleteAttachment deletes an attachment by name. - rpc DeleteAttachment(DeleteAttachmentRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=attachments/*}"}; - option (google.api.method_signature) = "name"; - } -} - -message Attachment { - option (google.api.resource) = { - type: "memos.api.v1/Attachment" - pattern: "attachments/{attachment}" - singular: "attachment" - plural: "attachments" - }; - - // The name of the attachment. - // Format: attachments/{attachment} - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // Output only. The creation timestamp. - google.protobuf.Timestamp create_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // The filename of the attachment. - string filename = 3 [(google.api.field_behavior) = REQUIRED]; - - // Input only. The content of the attachment. - bytes content = 4 [(google.api.field_behavior) = INPUT_ONLY]; - - // Optional. The external link of the attachment. - string external_link = 5 [(google.api.field_behavior) = OPTIONAL]; - - // The MIME type of the attachment. - string type = 6 [(google.api.field_behavior) = REQUIRED]; - - // Output only. The size of the attachment in bytes. - int64 size = 7 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Optional. The related memo. Refer to `Memo.name`. - // Format: memos/{memo} - optional string memo = 8 [(google.api.field_behavior) = OPTIONAL]; -} - -message CreateAttachmentRequest { - // Required. The attachment to create. - Attachment attachment = 1 [(google.api.field_behavior) = REQUIRED]; - - // Optional. The attachment ID to use for this attachment. - // If empty, a unique ID will be generated. - string attachment_id = 2 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListAttachmentsRequest { - // Optional. The maximum number of attachments to return. - // The service may return fewer than this value. - // If unspecified, at most 50 attachments will be returned. - // The maximum value is 1000; values above 1000 will be coerced to 1000. - int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token, received from a previous `ListAttachments` call. - // Provide this to retrieve the subsequent page. - string page_token = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. Filter to apply to the list results. - // Example: "mime_type==\"image/png\"" or "filename.contains(\"test\")" - // Supported operators: =, !=, <, <=, >, >=, : (contains), in - // Supported fields: filename, mime_type, create_time, memo - string filter = 3 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The order to sort results by. - // Example: "create_time desc" or "filename asc" - string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListAttachmentsResponse { - // The list of attachments. - repeated Attachment attachments = 1; - - // A token that can be sent as `page_token` to retrieve the next page. - // If this field is omitted, there are no subsequent pages. - string next_page_token = 2; - - // The total count of attachments (may be approximate). - int32 total_size = 3; -} - -message GetAttachmentRequest { - // Required. The attachment name of the attachment to retrieve. - // Format: attachments/{attachment} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Attachment"} - ]; -} - -message UpdateAttachmentRequest { - // Required. The attachment which replaces the attachment on the server. - Attachment attachment = 1 [(google.api.field_behavior) = REQUIRED]; - - // Required. The list of fields to update. - google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message DeleteAttachmentRequest { - // Required. The attachment name of the attachment to delete. - // Format: attachments/{attachment} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Attachment"} - ]; -} +syntax = "proto3"; + +package memos.api.v1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "gen/api/v1"; + +service AttachmentService { + // CreateAttachment creates a new attachment. + rpc CreateAttachment(CreateAttachmentRequest) returns (Attachment) { + option (google.api.http) = { + post: "/api/v1/attachments" + body: "attachment" + }; + option (google.api.method_signature) = "attachment"; + } + // ListAttachments lists all attachments. + rpc ListAttachments(ListAttachmentsRequest) returns (ListAttachmentsResponse) { + option (google.api.http) = {get: "/api/v1/attachments"}; + } + // GetAttachment returns an attachment by name. + rpc GetAttachment(GetAttachmentRequest) returns (Attachment) { + option (google.api.http) = {get: "/api/v1/{name=attachments/*}"}; + option (google.api.method_signature) = "name"; + } + // UpdateAttachment updates an attachment. + rpc UpdateAttachment(UpdateAttachmentRequest) returns (Attachment) { + option (google.api.http) = { + patch: "/api/v1/{attachment.name=attachments/*}" + body: "attachment" + }; + option (google.api.method_signature) = "attachment,update_mask"; + } + // DeleteAttachment deletes an attachment by name. + rpc DeleteAttachment(DeleteAttachmentRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=attachments/*}"}; + option (google.api.method_signature) = "name"; + } +} + +message Attachment { + option (google.api.resource) = { + type: "memos.api.v1/Attachment" + pattern: "attachments/{attachment}" + singular: "attachment" + plural: "attachments" + }; + + // The name of the attachment. + // Format: attachments/{attachment} + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // Output only. The creation timestamp. + google.protobuf.Timestamp create_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // The filename of the attachment. + string filename = 3 [(google.api.field_behavior) = REQUIRED]; + + // Input only. The content of the attachment. + bytes content = 4 [(google.api.field_behavior) = INPUT_ONLY]; + + // Optional. The external link of the attachment. + string external_link = 5 [(google.api.field_behavior) = OPTIONAL]; + + // The MIME type of the attachment. + string type = 6 [(google.api.field_behavior) = REQUIRED]; + + // Output only. The size of the attachment in bytes. + int64 size = 7 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Optional. The related memo. Refer to `Memo.name`. + // Format: memos/{memo} + optional string memo = 8 [(google.api.field_behavior) = OPTIONAL]; +} + +message CreateAttachmentRequest { + // Required. The attachment to create. + Attachment attachment = 1 [(google.api.field_behavior) = REQUIRED]; + + // Optional. The attachment ID to use for this attachment. + // If empty, a unique ID will be generated. + string attachment_id = 2 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListAttachmentsRequest { + // Optional. The maximum number of attachments to return. + // The service may return fewer than this value. + // If unspecified, at most 50 attachments will be returned. + // The maximum value is 1000; values above 1000 will be coerced to 1000. + int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token, received from a previous `ListAttachments` call. + // Provide this to retrieve the subsequent page. + string page_token = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. Filter to apply to the list results. + // Example: "mime_type==\"image/png\"" or "filename.contains(\"test\")" + // Supported operators: =, !=, <, <=, >, >=, : (contains), in + // Supported fields: filename, mime_type, create_time, memo + string filter = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The order to sort results by. + // Example: "create_time desc" or "filename asc" + string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListAttachmentsResponse { + // The list of attachments. + repeated Attachment attachments = 1; + + // A token that can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; + + // The total count of attachments (may be approximate). + int32 total_size = 3; +} + +message GetAttachmentRequest { + // Required. The attachment name of the attachment to retrieve. + // Format: attachments/{attachment} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Attachment"} + ]; +} + +message UpdateAttachmentRequest { + // Required. The attachment which replaces the attachment on the server. + Attachment attachment = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The list of fields to update. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message DeleteAttachmentRequest { + // Required. The attachment name of the attachment to delete. + // Format: attachments/{attachment} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Attachment"} + ]; +} diff --git a/proto/api/v1/auth_service.proto b/proto/api/v1/auth_service.proto index 8083a83fd..45a3a1d68 100644 --- a/proto/api/v1/auth_service.proto +++ b/proto/api/v1/auth_service.proto @@ -1,115 +1,115 @@ -syntax = "proto3"; - -package memos.api.v1; - -import "api/v1/user_service.proto"; -import "google/api/annotations.proto"; -import "google/api/field_behavior.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "gen/api/v1"; - -service AuthService { - // GetCurrentUser returns the authenticated user's information. - // Validates the access token and returns user details. - // Similar to OIDC's /userinfo endpoint. - rpc GetCurrentUser(GetCurrentUserRequest) returns (GetCurrentUserResponse) { - option (google.api.http) = {get: "/api/v1/auth/me"}; - } - - // SignIn authenticates a user with credentials and returns tokens. - // On success, returns an access token and sets a refresh token cookie. - // Supports password-based and SSO authentication methods. - rpc SignIn(SignInRequest) returns (SignInResponse) { - option (google.api.http) = { - post: "/api/v1/auth/signin" - body: "*" - }; - } - - // SignOut terminates the user's authentication. - // Revokes the refresh token and clears the authentication cookie. - rpc SignOut(SignOutRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {post: "/api/v1/auth/signout"}; - } - - // RefreshToken exchanges a valid refresh token for a new access token. - // The refresh token is read from the HttpOnly cookie. - // Returns a new short-lived access token. - rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse) { - option (google.api.http) = { - post: "/api/v1/auth/refresh" - body: "*" - }; - } -} - -message GetCurrentUserRequest {} - -message GetCurrentUserResponse { - // The authenticated user's information. - User user = 1; -} - -message SignInRequest { - // Nested message for password-based authentication credentials. - message PasswordCredentials { - // The username to sign in with. - string username = 1 [(google.api.field_behavior) = REQUIRED]; - - // The password to sign in with. - string password = 2 [(google.api.field_behavior) = REQUIRED]; - } - - // Nested message for SSO authentication credentials. - message SSOCredentials { - // The resource name of the SSO provider. - // Format: identity-providers/{uid} - string idp_name = 1 [(google.api.field_behavior) = REQUIRED]; - - // The authorization code from the SSO provider. - string code = 2 [(google.api.field_behavior) = REQUIRED]; - - // The redirect URI used in the SSO flow. - string redirect_uri = 3 [(google.api.field_behavior) = REQUIRED]; - - // The PKCE code verifier for enhanced security (RFC 7636). - // Optional - enables PKCE flow protection against authorization code interception. - string code_verifier = 4 [(google.api.field_behavior) = OPTIONAL]; - } - - // Authentication credentials. Provide one method. - oneof credentials { - // Username and password authentication. - PasswordCredentials password_credentials = 1; - - // SSO provider authentication. - SSOCredentials sso_credentials = 2; - } -} - -message SignInResponse { - // The authenticated user's information. - User user = 1; - - // The short-lived access token for API requests. - // Store in memory only, not in localStorage. - string access_token = 2; - - // When the access token expires. - // Client should call RefreshToken before this time. - google.protobuf.Timestamp access_token_expires_at = 3; -} - -message SignOutRequest {} - -message RefreshTokenRequest {} - -message RefreshTokenResponse { - // The new short-lived access token. - string access_token = 1; - - // When the access token expires. - google.protobuf.Timestamp expires_at = 2; -} +syntax = "proto3"; + +package memos.api.v1; + +import "api/v1/user_service.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "gen/api/v1"; + +service AuthService { + // GetCurrentUser returns the authenticated user's information. + // Validates the access token and returns user details. + // Similar to OIDC's /userinfo endpoint. + rpc GetCurrentUser(GetCurrentUserRequest) returns (GetCurrentUserResponse) { + option (google.api.http) = {get: "/api/v1/auth/me"}; + } + + // SignIn authenticates a user with credentials and returns tokens. + // On success, returns an access token and sets a refresh token cookie. + // Supports password-based and SSO authentication methods. + rpc SignIn(SignInRequest) returns (SignInResponse) { + option (google.api.http) = { + post: "/api/v1/auth/signin" + body: "*" + }; + } + + // SignOut terminates the user's authentication. + // Revokes the refresh token and clears the authentication cookie. + rpc SignOut(SignOutRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {post: "/api/v1/auth/signout"}; + } + + // RefreshToken exchanges a valid refresh token for a new access token. + // The refresh token is read from the HttpOnly cookie. + // Returns a new short-lived access token. + rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse) { + option (google.api.http) = { + post: "/api/v1/auth/refresh" + body: "*" + }; + } +} + +message GetCurrentUserRequest {} + +message GetCurrentUserResponse { + // The authenticated user's information. + User user = 1; +} + +message SignInRequest { + // Nested message for password-based authentication credentials. + message PasswordCredentials { + // The username to sign in with. + string username = 1 [(google.api.field_behavior) = REQUIRED]; + + // The password to sign in with. + string password = 2 [(google.api.field_behavior) = REQUIRED]; + } + + // Nested message for SSO authentication credentials. + message SSOCredentials { + // The resource name of the SSO provider. + // Format: identity-providers/{uid} + string idp_name = 1 [(google.api.field_behavior) = REQUIRED]; + + // The authorization code from the SSO provider. + string code = 2 [(google.api.field_behavior) = REQUIRED]; + + // The redirect URI used in the SSO flow. + string redirect_uri = 3 [(google.api.field_behavior) = REQUIRED]; + + // The PKCE code verifier for enhanced security (RFC 7636). + // Optional - enables PKCE flow protection against authorization code interception. + string code_verifier = 4 [(google.api.field_behavior) = OPTIONAL]; + } + + // Authentication credentials. Provide one method. + oneof credentials { + // Username and password authentication. + PasswordCredentials password_credentials = 1; + + // SSO provider authentication. + SSOCredentials sso_credentials = 2; + } +} + +message SignInResponse { + // The authenticated user's information. + User user = 1; + + // The short-lived access token for API requests. + // Store in memory only, not in localStorage. + string access_token = 2; + + // When the access token expires. + // Client should call RefreshToken before this time. + google.protobuf.Timestamp access_token_expires_at = 3; +} + +message SignOutRequest {} + +message RefreshTokenRequest {} + +message RefreshTokenResponse { + // The new short-lived access token. + string access_token = 1; + + // When the access token expires. + google.protobuf.Timestamp expires_at = 2; +} diff --git a/proto/api/v1/common.proto b/proto/api/v1/common.proto index 3aaa32634..6c5fcf880 100644 --- a/proto/api/v1/common.proto +++ b/proto/api/v1/common.proto @@ -1,23 +1,23 @@ -syntax = "proto3"; - -package memos.api.v1; - -option go_package = "gen/api/v1"; - -enum State { - STATE_UNSPECIFIED = 0; - NORMAL = 1; - ARCHIVED = 2; -} - -// Used internally for obfuscating the page token. -message PageToken { - int32 limit = 1; - int32 offset = 2; -} - -enum Direction { - DIRECTION_UNSPECIFIED = 0; - ASC = 1; - DESC = 2; -} +syntax = "proto3"; + +package memos.api.v1; + +option go_package = "gen/api/v1"; + +enum State { + STATE_UNSPECIFIED = 0; + NORMAL = 1; + ARCHIVED = 2; +} + +// Used internally for obfuscating the page token. +message PageToken { + int32 limit = 1; + int32 offset = 2; +} + +enum Direction { + DIRECTION_UNSPECIFIED = 0; + ASC = 1; + DESC = 2; +} diff --git a/proto/api/v1/idp_service.proto b/proto/api/v1/idp_service.proto index d89734a45..e64f4f6d1 100644 --- a/proto/api/v1/idp_service.proto +++ b/proto/api/v1/idp_service.proto @@ -1,147 +1,147 @@ -syntax = "proto3"; - -package memos.api.v1; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/field_mask.proto"; - -option go_package = "gen/api/v1"; - -service IdentityProviderService { - // ListIdentityProviders lists identity providers. - rpc ListIdentityProviders(ListIdentityProvidersRequest) returns (ListIdentityProvidersResponse) { - option (google.api.http) = {get: "/api/v1/identity-providers"}; - } - - // GetIdentityProvider gets an identity provider. - rpc GetIdentityProvider(GetIdentityProviderRequest) returns (IdentityProvider) { - option (google.api.http) = {get: "/api/v1/{name=identity-providers/*}"}; - option (google.api.method_signature) = "name"; - } - - // CreateIdentityProvider creates an identity provider. - rpc CreateIdentityProvider(CreateIdentityProviderRequest) returns (IdentityProvider) { - option (google.api.http) = { - post: "/api/v1/identity-providers" - body: "identity_provider" - }; - option (google.api.method_signature) = "identity_provider"; - } - - // UpdateIdentityProvider updates an identity provider. - rpc UpdateIdentityProvider(UpdateIdentityProviderRequest) returns (IdentityProvider) { - option (google.api.http) = { - patch: "/api/v1/{identity_provider.name=identity-providers/*}" - body: "identity_provider" - }; - option (google.api.method_signature) = "identity_provider,update_mask"; - } - - // DeleteIdentityProvider deletes an identity provider. - rpc DeleteIdentityProvider(DeleteIdentityProviderRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=identity-providers/*}"}; - option (google.api.method_signature) = "name"; - } -} - -message IdentityProvider { - option (google.api.resource) = { - type: "memos.api.v1/IdentityProvider" - pattern: "identity-providers/{idp}" - name_field: "name" - singular: "identityProvider" - plural: "identityProviders" - }; - - // The resource name of the identity provider. - // Format: identity-providers/{idp} - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // Required. The type of the identity provider. - Type type = 2 [(google.api.field_behavior) = REQUIRED]; - - // Required. The display title of the identity provider. - string title = 3 [(google.api.field_behavior) = REQUIRED]; - - // Optional. Filter applied to user identifiers. - string identifier_filter = 4 [(google.api.field_behavior) = OPTIONAL]; - - // Required. Configuration for the identity provider. - IdentityProviderConfig config = 5 [(google.api.field_behavior) = REQUIRED]; - - enum Type { - TYPE_UNSPECIFIED = 0; - // OAuth2 identity provider. - OAUTH2 = 1; - } -} - -message IdentityProviderConfig { - oneof config { - OAuth2Config oauth2_config = 1; - } -} - -message FieldMapping { - string identifier = 1; - string display_name = 2; - string email = 3; - string avatar_url = 4; -} - -message OAuth2Config { - string client_id = 1; - string client_secret = 2; - string auth_url = 3; - string token_url = 4; - string user_info_url = 5; - repeated string scopes = 6; - FieldMapping field_mapping = 7; -} - -message ListIdentityProvidersRequest {} - -message ListIdentityProvidersResponse { - // The list of identity providers. - repeated IdentityProvider identity_providers = 1; -} - -message GetIdentityProviderRequest { - // Required. The resource name of the identity provider to get. - // Format: identity-providers/{idp} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/IdentityProvider"} - ]; -} - -message CreateIdentityProviderRequest { - // Required. The identity provider to create. - IdentityProvider identity_provider = 1 [(google.api.field_behavior) = REQUIRED]; - - // Optional. The ID to use for the identity provider, which will become the final component of the resource name. - // If not provided, the system will generate one. - string identity_provider_id = 2 [(google.api.field_behavior) = OPTIONAL]; -} - -message UpdateIdentityProviderRequest { - // Required. The identity provider to update. - IdentityProvider identity_provider = 1 [(google.api.field_behavior) = REQUIRED]; - - // Required. The update mask applies to the resource. Only the top level fields of - // IdentityProvider are supported. - google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message DeleteIdentityProviderRequest { - // Required. The resource name of the identity provider to delete. - // Format: identity-providers/{idp} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/IdentityProvider"} - ]; -} +syntax = "proto3"; + +package memos.api.v1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; + +option go_package = "gen/api/v1"; + +service IdentityProviderService { + // ListIdentityProviders lists identity providers. + rpc ListIdentityProviders(ListIdentityProvidersRequest) returns (ListIdentityProvidersResponse) { + option (google.api.http) = {get: "/api/v1/identity-providers"}; + } + + // GetIdentityProvider gets an identity provider. + rpc GetIdentityProvider(GetIdentityProviderRequest) returns (IdentityProvider) { + option (google.api.http) = {get: "/api/v1/{name=identity-providers/*}"}; + option (google.api.method_signature) = "name"; + } + + // CreateIdentityProvider creates an identity provider. + rpc CreateIdentityProvider(CreateIdentityProviderRequest) returns (IdentityProvider) { + option (google.api.http) = { + post: "/api/v1/identity-providers" + body: "identity_provider" + }; + option (google.api.method_signature) = "identity_provider"; + } + + // UpdateIdentityProvider updates an identity provider. + rpc UpdateIdentityProvider(UpdateIdentityProviderRequest) returns (IdentityProvider) { + option (google.api.http) = { + patch: "/api/v1/{identity_provider.name=identity-providers/*}" + body: "identity_provider" + }; + option (google.api.method_signature) = "identity_provider,update_mask"; + } + + // DeleteIdentityProvider deletes an identity provider. + rpc DeleteIdentityProvider(DeleteIdentityProviderRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=identity-providers/*}"}; + option (google.api.method_signature) = "name"; + } +} + +message IdentityProvider { + option (google.api.resource) = { + type: "memos.api.v1/IdentityProvider" + pattern: "identity-providers/{idp}" + name_field: "name" + singular: "identityProvider" + plural: "identityProviders" + }; + + // The resource name of the identity provider. + // Format: identity-providers/{idp} + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // Required. The type of the identity provider. + Type type = 2 [(google.api.field_behavior) = REQUIRED]; + + // Required. The display title of the identity provider. + string title = 3 [(google.api.field_behavior) = REQUIRED]; + + // Optional. Filter applied to user identifiers. + string identifier_filter = 4 [(google.api.field_behavior) = OPTIONAL]; + + // Required. Configuration for the identity provider. + IdentityProviderConfig config = 5 [(google.api.field_behavior) = REQUIRED]; + + enum Type { + TYPE_UNSPECIFIED = 0; + // OAuth2 identity provider. + OAUTH2 = 1; + } +} + +message IdentityProviderConfig { + oneof config { + OAuth2Config oauth2_config = 1; + } +} + +message FieldMapping { + string identifier = 1; + string display_name = 2; + string email = 3; + string avatar_url = 4; +} + +message OAuth2Config { + string client_id = 1; + string client_secret = 2; + string auth_url = 3; + string token_url = 4; + string user_info_url = 5; + repeated string scopes = 6; + FieldMapping field_mapping = 7; +} + +message ListIdentityProvidersRequest {} + +message ListIdentityProvidersResponse { + // The list of identity providers. + repeated IdentityProvider identity_providers = 1; +} + +message GetIdentityProviderRequest { + // Required. The resource name of the identity provider to get. + // Format: identity-providers/{idp} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/IdentityProvider"} + ]; +} + +message CreateIdentityProviderRequest { + // Required. The identity provider to create. + IdentityProvider identity_provider = 1 [(google.api.field_behavior) = REQUIRED]; + + // Optional. The ID to use for the identity provider, which will become the final component of the resource name. + // If not provided, the system will generate one. + string identity_provider_id = 2 [(google.api.field_behavior) = OPTIONAL]; +} + +message UpdateIdentityProviderRequest { + // Required. The identity provider to update. + IdentityProvider identity_provider = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The update mask applies to the resource. Only the top level fields of + // IdentityProvider are supported. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message DeleteIdentityProviderRequest { + // Required. The resource name of the identity provider to delete. + // Format: identity-providers/{idp} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/IdentityProvider"} + ]; +} diff --git a/proto/api/v1/instance_service.proto b/proto/api/v1/instance_service.proto index f1357d00a..836a2415e 100644 --- a/proto/api/v1/instance_service.proto +++ b/proto/api/v1/instance_service.proto @@ -1,220 +1,220 @@ -syntax = "proto3"; - -package memos.api.v1; - -import "api/v1/user_service.proto"; -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/protobuf/field_mask.proto"; -import "google/type/color.proto"; - -option go_package = "gen/api/v1"; - -service InstanceService { - // Gets the instance profile. - rpc GetInstanceProfile(GetInstanceProfileRequest) returns (InstanceProfile) { - option (google.api.http) = {get: "/api/v1/instance/profile"}; - } - - // Gets an instance setting. - rpc GetInstanceSetting(GetInstanceSettingRequest) returns (InstanceSetting) { - option (google.api.http) = {get: "/api/v1/{name=instance/settings/*}"}; - option (google.api.method_signature) = "name"; - } - - // Updates an instance setting. - rpc UpdateInstanceSetting(UpdateInstanceSettingRequest) returns (InstanceSetting) { - option (google.api.http) = { - patch: "/api/v1/{setting.name=instance/settings/*}" - body: "setting" - }; - option (google.api.method_signature) = "setting,update_mask"; - } -} - -// Instance profile message containing basic instance information. -message InstanceProfile { - // Version is the current version of instance. - string version = 2; - - // Demo indicates if the instance is in demo mode. - bool demo = 3; - - // Instance URL is the URL of the instance. - string instance_url = 6; - - // The first administrator who set up this instance. - // When null, instance requires initial setup (creating the first admin account). - User admin = 7; -} - -// Request for instance profile. -message GetInstanceProfileRequest {} - -// An instance setting resource. -message InstanceSetting { - option (google.api.resource) = { - type: "memos.api.v1/InstanceSetting" - pattern: "instance/settings/{setting}" - singular: "instanceSetting" - plural: "instanceSettings" - }; - - // The name of the instance setting. - // Format: instance/settings/{setting} - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - oneof value { - GeneralSetting general_setting = 2; - StorageSetting storage_setting = 3; - MemoRelatedSetting memo_related_setting = 4; - TagsSetting tags_setting = 5; - NotificationSetting notification_setting = 6; - } - - // Enumeration of instance setting keys. - enum Key { - KEY_UNSPECIFIED = 0; - // GENERAL is the key for general settings. - GENERAL = 1; - // STORAGE is the key for storage settings. - STORAGE = 2; - // MEMO_RELATED is the key for memo related settings. - MEMO_RELATED = 3; - // TAGS is the key for tag metadata. - TAGS = 4; - // NOTIFICATION is the key for notification transport settings. - NOTIFICATION = 5; - } - - // General instance settings configuration. - message GeneralSetting { - // disallow_user_registration disallows user registration. - bool disallow_user_registration = 2; - // disallow_password_auth disallows password authentication. - bool disallow_password_auth = 3; - // additional_script is the additional script. - string additional_script = 4; - // additional_style is the additional style. - string additional_style = 5; - // custom_profile is the custom profile. - CustomProfile custom_profile = 6; - // week_start_day_offset is the week start day offset from Sunday. - // 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday - // Default is Sunday. - int32 week_start_day_offset = 7; - - // disallow_change_username disallows changing username. - bool disallow_change_username = 8; - // disallow_change_nickname disallows changing nickname. - bool disallow_change_nickname = 9; - - // Custom profile configuration for instance branding. - message CustomProfile { - string title = 1; - string description = 2; - string logo_url = 3; - } - } - - // Storage configuration settings for instance attachments. - message StorageSetting { - // Storage type enumeration for different storage backends. - enum StorageType { - STORAGE_TYPE_UNSPECIFIED = 0; - // DATABASE is the database storage type. - DATABASE = 1; - // LOCAL is the local storage type. - LOCAL = 2; - // S3 is the S3 storage type. - S3 = 3; - } - // storage_type is the storage type. - StorageType storage_type = 1; - // The template of file path. - // e.g. assets/{timestamp}_{filename} - string filepath_template = 2; - // The max upload size in megabytes. - int64 upload_size_limit_mb = 3; - - // S3 configuration for cloud storage backend. - // Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/ - message S3Config { - string access_key_id = 1; - string access_key_secret = 2; - string endpoint = 3; - string region = 4; - string bucket = 5; - bool use_path_style = 6; - } - // The S3 config. - S3Config s3_config = 4; - } - - // Memo-related instance settings and policies. - message MemoRelatedSetting { - // display_with_update_time orders and displays memo with update time. - bool display_with_update_time = 2; - // content_length_limit is the limit of content length. Unit is byte. - int32 content_length_limit = 3; - // enable_double_click_edit enables editing on double click. - bool enable_double_click_edit = 4; - // reactions is the list of reactions. - repeated string reactions = 7; - } - - // Metadata for a tag. - message TagMetadata { - // Background color for the tag label. - google.type.Color background_color = 1; - } - - // Tag metadata configuration. - message TagsSetting { - // Map of tag name pattern to tag metadata. - // Each key is treated as an anchored regular expression (^pattern$), - // so a single entry like "project/.*" matches all tags under that prefix. - // Exact tag names are also valid (they are trivially valid regex patterns). - map tags = 1; - } - - // Notification transport configuration. - message NotificationSetting { - EmailSetting email = 1; - - // Email delivery configuration for notifications. - message EmailSetting { - bool enabled = 1; - string smtp_host = 2; - int32 smtp_port = 3; - string smtp_username = 4; - string smtp_password = 5; - string from_email = 6; - string from_name = 7; - string reply_to = 8; - bool use_tls = 9; - bool use_ssl = 10; - } - } -} - -// Request message for GetInstanceSetting method. -message GetInstanceSettingRequest { - // The resource name of the instance setting. - // Format: instance/settings/{setting} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/InstanceSetting"} - ]; -} - -// Request message for UpdateInstanceSetting method. -message UpdateInstanceSettingRequest { - // The instance setting resource which replaces the resource on the server. - InstanceSetting setting = 1 [(google.api.field_behavior) = REQUIRED]; - - // The list of fields to update. - google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL]; -} +syntax = "proto3"; + +package memos.api.v1; + +import "api/v1/user_service.proto"; +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/field_mask.proto"; +import "google/type/color.proto"; + +option go_package = "gen/api/v1"; + +service InstanceService { + // Gets the instance profile. + rpc GetInstanceProfile(GetInstanceProfileRequest) returns (InstanceProfile) { + option (google.api.http) = {get: "/api/v1/instance/profile"}; + } + + // Gets an instance setting. + rpc GetInstanceSetting(GetInstanceSettingRequest) returns (InstanceSetting) { + option (google.api.http) = {get: "/api/v1/{name=instance/settings/*}"}; + option (google.api.method_signature) = "name"; + } + + // Updates an instance setting. + rpc UpdateInstanceSetting(UpdateInstanceSettingRequest) returns (InstanceSetting) { + option (google.api.http) = { + patch: "/api/v1/{setting.name=instance/settings/*}" + body: "setting" + }; + option (google.api.method_signature) = "setting,update_mask"; + } +} + +// Instance profile message containing basic instance information. +message InstanceProfile { + // Version is the current version of instance. + string version = 2; + + // Demo indicates if the instance is in demo mode. + bool demo = 3; + + // Instance URL is the URL of the instance. + string instance_url = 6; + + // The first administrator who set up this instance. + // When null, instance requires initial setup (creating the first admin account). + User admin = 7; +} + +// Request for instance profile. +message GetInstanceProfileRequest {} + +// An instance setting resource. +message InstanceSetting { + option (google.api.resource) = { + type: "memos.api.v1/InstanceSetting" + pattern: "instance/settings/{setting}" + singular: "instanceSetting" + plural: "instanceSettings" + }; + + // The name of the instance setting. + // Format: instance/settings/{setting} + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + oneof value { + GeneralSetting general_setting = 2; + StorageSetting storage_setting = 3; + MemoRelatedSetting memo_related_setting = 4; + TagsSetting tags_setting = 5; + NotificationSetting notification_setting = 6; + } + + // Enumeration of instance setting keys. + enum Key { + KEY_UNSPECIFIED = 0; + // GENERAL is the key for general settings. + GENERAL = 1; + // STORAGE is the key for storage settings. + STORAGE = 2; + // MEMO_RELATED is the key for memo related settings. + MEMO_RELATED = 3; + // TAGS is the key for tag metadata. + TAGS = 4; + // NOTIFICATION is the key for notification transport settings. + NOTIFICATION = 5; + } + + // General instance settings configuration. + message GeneralSetting { + // disallow_user_registration disallows user registration. + bool disallow_user_registration = 2; + // disallow_password_auth disallows password authentication. + bool disallow_password_auth = 3; + // additional_script is the additional script. + string additional_script = 4; + // additional_style is the additional style. + string additional_style = 5; + // custom_profile is the custom profile. + CustomProfile custom_profile = 6; + // week_start_day_offset is the week start day offset from Sunday. + // 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday + // Default is Sunday. + int32 week_start_day_offset = 7; + + // disallow_change_username disallows changing username. + bool disallow_change_username = 8; + // disallow_change_nickname disallows changing nickname. + bool disallow_change_nickname = 9; + + // Custom profile configuration for instance branding. + message CustomProfile { + string title = 1; + string description = 2; + string logo_url = 3; + } + } + + // Storage configuration settings for instance attachments. + message StorageSetting { + // Storage type enumeration for different storage backends. + enum StorageType { + STORAGE_TYPE_UNSPECIFIED = 0; + // DATABASE is the database storage type. + DATABASE = 1; + // LOCAL is the local storage type. + LOCAL = 2; + // S3 is the S3 storage type. + S3 = 3; + } + // storage_type is the storage type. + StorageType storage_type = 1; + // The template of file path. + // e.g. assets/{timestamp}_{filename} + string filepath_template = 2; + // The max upload size in megabytes. + int64 upload_size_limit_mb = 3; + + // S3 configuration for cloud storage backend. + // Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/ + message S3Config { + string access_key_id = 1; + string access_key_secret = 2; + string endpoint = 3; + string region = 4; + string bucket = 5; + bool use_path_style = 6; + } + // The S3 config. + S3Config s3_config = 4; + } + + // Memo-related instance settings and policies. + message MemoRelatedSetting { + // display_with_update_time orders and displays memo with update time. + bool display_with_update_time = 2; + // content_length_limit is the limit of content length. Unit is byte. + int32 content_length_limit = 3; + // enable_double_click_edit enables editing on double click. + bool enable_double_click_edit = 4; + // reactions is the list of reactions. + repeated string reactions = 7; + } + + // Metadata for a tag. + message TagMetadata { + // Background color for the tag label. + google.type.Color background_color = 1; + } + + // Tag metadata configuration. + message TagsSetting { + // Map of tag name pattern to tag metadata. + // Each key is treated as an anchored regular expression (^pattern$), + // so a single entry like "project/.*" matches all tags under that prefix. + // Exact tag names are also valid (they are trivially valid regex patterns). + map tags = 1; + } + + // Notification transport configuration. + message NotificationSetting { + EmailSetting email = 1; + + // Email delivery configuration for notifications. + message EmailSetting { + bool enabled = 1; + string smtp_host = 2; + int32 smtp_port = 3; + string smtp_username = 4; + string smtp_password = 5; + string from_email = 6; + string from_name = 7; + string reply_to = 8; + bool use_tls = 9; + bool use_ssl = 10; + } + } +} + +// Request message for GetInstanceSetting method. +message GetInstanceSettingRequest { + // The resource name of the instance setting. + // Format: instance/settings/{setting} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/InstanceSetting"} + ]; +} + +// Request message for UpdateInstanceSetting method. +message UpdateInstanceSettingRequest { + // The instance setting resource which replaces the resource on the server. + InstanceSetting setting = 1 [(google.api.field_behavior) = REQUIRED]; + + // The list of fields to update. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL]; +} diff --git a/proto/api/v1/memo_service.proto b/proto/api/v1/memo_service.proto index 737fb206a..9f697d173 100644 --- a/proto/api/v1/memo_service.proto +++ b/proto/api/v1/memo_service.proto @@ -1,597 +1,597 @@ -syntax = "proto3"; - -package memos.api.v1; - -import "api/v1/attachment_service.proto"; -import "api/v1/common.proto"; -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/field_mask.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "gen/api/v1"; - -service MemoService { - // CreateMemo creates a memo. - rpc CreateMemo(CreateMemoRequest) returns (Memo) { - option (google.api.http) = { - post: "/api/v1/memos" - body: "memo" - }; - option (google.api.method_signature) = "memo"; - } - // ListMemos lists memos with pagination and filter. - rpc ListMemos(ListMemosRequest) returns (ListMemosResponse) { - option (google.api.http) = {get: "/api/v1/memos"}; - option (google.api.method_signature) = ""; - } - // GetMemo gets a memo. - rpc GetMemo(GetMemoRequest) returns (Memo) { - option (google.api.http) = {get: "/api/v1/{name=memos/*}"}; - option (google.api.method_signature) = "name"; - } - // UpdateMemo updates a memo. - rpc UpdateMemo(UpdateMemoRequest) returns (Memo) { - option (google.api.http) = { - patch: "/api/v1/{memo.name=memos/*}" - body: "memo" - }; - option (google.api.method_signature) = "memo,update_mask"; - } - // DeleteMemo deletes a memo. - rpc DeleteMemo(DeleteMemoRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=memos/*}"}; - option (google.api.method_signature) = "name"; - } - // SetMemoAttachments sets attachments for a memo. - rpc SetMemoAttachments(SetMemoAttachmentsRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - patch: "/api/v1/{name=memos/*}/attachments" - body: "*" - }; - option (google.api.method_signature) = "name"; - } - // ListMemoAttachments lists attachments for a memo. - rpc ListMemoAttachments(ListMemoAttachmentsRequest) returns (ListMemoAttachmentsResponse) { - option (google.api.http) = {get: "/api/v1/{name=memos/*}/attachments"}; - option (google.api.method_signature) = "name"; - } - // SetMemoRelations sets relations for a memo. - rpc SetMemoRelations(SetMemoRelationsRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - patch: "/api/v1/{name=memos/*}/relations" - body: "*" - }; - option (google.api.method_signature) = "name"; - } - // ListMemoRelations lists relations for a memo. - rpc ListMemoRelations(ListMemoRelationsRequest) returns (ListMemoRelationsResponse) { - option (google.api.http) = {get: "/api/v1/{name=memos/*}/relations"}; - option (google.api.method_signature) = "name"; - } - // CreateMemoComment creates a comment for a memo. - rpc CreateMemoComment(CreateMemoCommentRequest) returns (Memo) { - option (google.api.http) = { - post: "/api/v1/{name=memos/*}/comments" - body: "comment" - }; - option (google.api.method_signature) = "name,comment"; - } - // ListMemoComments lists comments for a memo. - rpc ListMemoComments(ListMemoCommentsRequest) returns (ListMemoCommentsResponse) { - option (google.api.http) = {get: "/api/v1/{name=memos/*}/comments"}; - option (google.api.method_signature) = "name"; - } - // ListMemoReactions lists reactions for a memo. - rpc ListMemoReactions(ListMemoReactionsRequest) returns (ListMemoReactionsResponse) { - option (google.api.http) = {get: "/api/v1/{name=memos/*}/reactions"}; - option (google.api.method_signature) = "name"; - } - // UpsertMemoReaction upserts a reaction for a memo. - rpc UpsertMemoReaction(UpsertMemoReactionRequest) returns (Reaction) { - option (google.api.http) = { - post: "/api/v1/{name=memos/*}/reactions" - body: "*" - }; - option (google.api.method_signature) = "name"; - } - // DeleteMemoReaction deletes a reaction for a memo. - rpc DeleteMemoReaction(DeleteMemoReactionRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=memos/*/reactions/*}"}; - option (google.api.method_signature) = "name"; - } - // CreateMemoShare creates a share link for a memo. Requires authentication as the memo creator. - rpc CreateMemoShare(CreateMemoShareRequest) returns (MemoShare) { - option (google.api.http) = { - post: "/api/v1/{parent=memos/*}/shares" - body: "memo_share" - }; - option (google.api.method_signature) = "parent,memo_share"; - } - // ListMemoShares lists all share links for a memo. Requires authentication as the memo creator. - rpc ListMemoShares(ListMemoSharesRequest) returns (ListMemoSharesResponse) { - option (google.api.http) = {get: "/api/v1/{parent=memos/*}/shares"}; - option (google.api.method_signature) = "parent"; - } - // DeleteMemoShare revokes a share link. Requires authentication as the memo creator. - rpc DeleteMemoShare(DeleteMemoShareRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=memos/*/shares/*}"}; - option (google.api.method_signature) = "name"; - } - // GetMemoByShare resolves a share token to its memo. No authentication required. - // Returns NOT_FOUND if the token is invalid or expired. - rpc GetMemoByShare(GetMemoByShareRequest) returns (Memo) { - option (google.api.http) = {get: "/api/v1/shares/{share_id}"}; - } -} - -enum Visibility { - VISIBILITY_UNSPECIFIED = 0; - PRIVATE = 1; - PROTECTED = 2; - PUBLIC = 3; -} - -message Reaction { - option (google.api.resource) = { - type: "memos.api.v1/Reaction" - pattern: "memos/{memo}/reactions/{reaction}" - name_field: "name" - singular: "reaction" - plural: "reactions" - }; - - // The resource name of the reaction. - // Format: memos/{memo}/reactions/{reaction} - string name = 1 [ - (google.api.field_behavior) = OUTPUT_ONLY, - (google.api.field_behavior) = IDENTIFIER - ]; - - // The resource name of the creator. - // Format: users/{user} - string creator = 2 [ - (google.api.field_behavior) = OUTPUT_ONLY, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - // The resource name of the content. - // For memo reactions, this should be the memo's resource name. - // Format: memos/{memo} - string content_id = 3 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Required. The type of reaction (e.g., "👍", "❤️", "😄"). - string reaction_type = 4 [(google.api.field_behavior) = REQUIRED]; - - // Output only. The creation timestamp. - google.protobuf.Timestamp create_time = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; -} - -message Memo { - option (google.api.resource) = { - type: "memos.api.v1/Memo" - pattern: "memos/{memo}" - name_field: "name" - singular: "memo" - plural: "memos" - }; - - // The resource name of the memo. - // Format: memos/{memo}, memo is the user defined id or uuid. - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // The state of the memo. - State state = 2 [(google.api.field_behavior) = REQUIRED]; - - // The name of the creator. - // Format: users/{user} - string creator = 3 [ - (google.api.field_behavior) = OUTPUT_ONLY, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - // The creation timestamp. - // If not set on creation, the server will set it to the current time. - google.protobuf.Timestamp create_time = 4 [(google.api.field_behavior) = OPTIONAL]; - - // The last update timestamp. - // If not set on creation, the server will set it to the current time. - google.protobuf.Timestamp update_time = 5 [(google.api.field_behavior) = OPTIONAL]; - - // The display timestamp of the memo. - google.protobuf.Timestamp display_time = 6 [(google.api.field_behavior) = OPTIONAL]; - - // Required. The content of the memo in Markdown format. - string content = 7 [(google.api.field_behavior) = REQUIRED]; - - // The visibility of the memo. - Visibility visibility = 9 [(google.api.field_behavior) = REQUIRED]; - - // Output only. The tags extracted from the content. - repeated string tags = 10 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Whether the memo is pinned. - bool pinned = 11 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The attachments of the memo. - repeated Attachment attachments = 12 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The relations of the memo. - repeated MemoRelation relations = 13 [(google.api.field_behavior) = OPTIONAL]; - - // Output only. The reactions to the memo. - repeated Reaction reactions = 14 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Output only. The computed properties of the memo. - Property property = 15 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Output only. The name of the parent memo. - // Format: memos/{memo} - optional string parent = 16 [ - (google.api.field_behavior) = OUTPUT_ONLY, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Output only. The snippet of the memo content. Plain text only. - string snippet = 17 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Optional. The location of the memo. - optional Location location = 18 [(google.api.field_behavior) = OPTIONAL]; - - // Computed properties of a memo. - message Property { - bool has_link = 1; - bool has_task_list = 2; - bool has_code = 3; - bool has_incomplete_tasks = 4; - // The title extracted from the first H1 heading, if present. - string title = 5; - } -} - -message Location { - // A placeholder text for the location. - string placeholder = 1 [(google.api.field_behavior) = OPTIONAL]; - - // The latitude of the location. - double latitude = 2 [(google.api.field_behavior) = OPTIONAL]; - - // The longitude of the location. - double longitude = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message CreateMemoRequest { - // Required. The memo to create. - Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; - - // Optional. The memo ID to use for this memo. - // If empty, a unique ID will be generated. - string memo_id = 2 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListMemosRequest { - // Optional. The maximum number of memos to return. - // The service may return fewer than this value. - // If unspecified, at most 50 memos will be returned. - // The maximum value is 1000; values above 1000 will be coerced to 1000. - int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token, received from a previous `ListMemos` call. - // Provide this to retrieve the subsequent page. - string page_token = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The state of the memos to list. - // Default to `NORMAL`. Set to `ARCHIVED` to list archived memos. - State state = 3 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The order to sort results by. - // Default to "display_time desc". - // Supports comma-separated list of fields following AIP-132. - // Example: "pinned desc, display_time desc" or "create_time asc" - // Supported fields: pinned, display_time, create_time, update_time, name - string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. Filter to apply to the list results. - // Filter is a CEL expression to filter memos. - // Refer to `Shortcut.filter`. - string filter = 5 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. If true, show deleted memos in the response. - bool show_deleted = 6 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListMemosResponse { - // The list of memos. - repeated Memo memos = 1; - - // A token that can be sent as `page_token` to retrieve the next page. - // If this field is omitted, there are no subsequent pages. - string next_page_token = 2; -} - -message GetMemoRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; -} - -message UpdateMemoRequest { - // Required. The memo to update. - // The `name` field is required. - Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; - - // Required. The list of fields to update. - google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message DeleteMemoRequest { - // Required. The resource name of the memo to delete. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Optional. If set to true, the memo will be deleted even if it has associated data. - bool force = 2 [(google.api.field_behavior) = OPTIONAL]; -} - -message SetMemoAttachmentsRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Required. The attachments to set for the memo. - repeated Attachment attachments = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message ListMemoAttachmentsRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Optional. The maximum number of attachments to return. - int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token for pagination. - string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListMemoAttachmentsResponse { - // The list of attachments. - repeated Attachment attachments = 1; - - // A token for the next page of results. - string next_page_token = 2; -} - -message MemoRelation { - // The memo in the relation. - Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; - - // The related memo. - Memo related_memo = 2 [(google.api.field_behavior) = REQUIRED]; - - // The type of the relation. - enum Type { - TYPE_UNSPECIFIED = 0; - REFERENCE = 1; - COMMENT = 2; - } - Type type = 3 [(google.api.field_behavior) = REQUIRED]; - - // Memo reference in relations. - message Memo { - // The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Output only. The snippet of the memo content. Plain text only. - string snippet = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; - } -} - -message SetMemoRelationsRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Required. The relations to set for the memo. - repeated MemoRelation relations = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message ListMemoRelationsRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Optional. The maximum number of relations to return. - int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token for pagination. - string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListMemoRelationsResponse { - // The list of relations. - repeated MemoRelation relations = 1; - - // A token for the next page of results. - string next_page_token = 2; -} - -message CreateMemoCommentRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Required. The comment to create. - Memo comment = 2 [(google.api.field_behavior) = REQUIRED]; - - // Optional. The comment ID to use. - string comment_id = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListMemoCommentsRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Optional. The maximum number of comments to return. - int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token for pagination. - string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The order to sort results by. - string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListMemoCommentsResponse { - // The list of comment memos. - repeated Memo memos = 1; - - // A token for the next page of results. - string next_page_token = 2; - - // The total count of comments. - int32 total_size = 3; -} - -message ListMemoReactionsRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Optional. The maximum number of reactions to return. - int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token for pagination. - string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListMemoReactionsResponse { - // The list of reactions. - repeated Reaction reactions = 1; - - // A token for the next page of results. - string next_page_token = 2; - - // The total count of reactions. - int32 total_size = 3; -} - -message UpsertMemoReactionRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Required. The reaction to upsert. - Reaction reaction = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message DeleteMemoReactionRequest { - // Required. The resource name of the reaction to delete. - // Format: memos/{memo}/reactions/{reaction} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Reaction"} - ]; -} - -// MemoShare is an access grant that permits read-only access to a memo via an opaque bearer token. -message MemoShare { - option (google.api.resource) = { - type: "memos.api.v1/MemoShare" - pattern: "memos/{memo}/shares/{share}" - singular: "share" - plural: "shares" - }; - - // The resource name of the share. Format: memos/{memo}/shares/{share} - // The {share} segment is the opaque token used in the share URL. - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // Output only. When this share link was created. - google.protobuf.Timestamp create_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Optional. When set, the share link stops working after this time. - // If unset, the link never expires. - optional google.protobuf.Timestamp expire_time = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message CreateMemoShareRequest { - // Required. The resource name of the memo to share. - // Format: memos/{memo} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; - - // Required. The share to create. - MemoShare memo_share = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message ListMemoSharesRequest { - // Required. The resource name of the memo. - // Format: memos/{memo} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Memo"} - ]; -} - -message ListMemoSharesResponse { - // The list of share links. - repeated MemoShare memo_shares = 1; -} - -message DeleteMemoShareRequest { - // Required. The resource name of the share to delete. - // Format: memos/{memo}/shares/{share} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/MemoShare"} - ]; -} - -message GetMemoByShareRequest { - // Required. The share token extracted from the share URL (/s/{share_id}). - string share_id = 1 [(google.api.field_behavior) = REQUIRED]; -} +syntax = "proto3"; + +package memos.api.v1; + +import "api/v1/attachment_service.proto"; +import "api/v1/common.proto"; +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "gen/api/v1"; + +service MemoService { + // CreateMemo creates a memo. + rpc CreateMemo(CreateMemoRequest) returns (Memo) { + option (google.api.http) = { + post: "/api/v1/memos" + body: "memo" + }; + option (google.api.method_signature) = "memo"; + } + // ListMemos lists memos with pagination and filter. + rpc ListMemos(ListMemosRequest) returns (ListMemosResponse) { + option (google.api.http) = {get: "/api/v1/memos"}; + option (google.api.method_signature) = ""; + } + // GetMemo gets a memo. + rpc GetMemo(GetMemoRequest) returns (Memo) { + option (google.api.http) = {get: "/api/v1/{name=memos/*}"}; + option (google.api.method_signature) = "name"; + } + // UpdateMemo updates a memo. + rpc UpdateMemo(UpdateMemoRequest) returns (Memo) { + option (google.api.http) = { + patch: "/api/v1/{memo.name=memos/*}" + body: "memo" + }; + option (google.api.method_signature) = "memo,update_mask"; + } + // DeleteMemo deletes a memo. + rpc DeleteMemo(DeleteMemoRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=memos/*}"}; + option (google.api.method_signature) = "name"; + } + // SetMemoAttachments sets attachments for a memo. + rpc SetMemoAttachments(SetMemoAttachmentsRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + patch: "/api/v1/{name=memos/*}/attachments" + body: "*" + }; + option (google.api.method_signature) = "name"; + } + // ListMemoAttachments lists attachments for a memo. + rpc ListMemoAttachments(ListMemoAttachmentsRequest) returns (ListMemoAttachmentsResponse) { + option (google.api.http) = {get: "/api/v1/{name=memos/*}/attachments"}; + option (google.api.method_signature) = "name"; + } + // SetMemoRelations sets relations for a memo. + rpc SetMemoRelations(SetMemoRelationsRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + patch: "/api/v1/{name=memos/*}/relations" + body: "*" + }; + option (google.api.method_signature) = "name"; + } + // ListMemoRelations lists relations for a memo. + rpc ListMemoRelations(ListMemoRelationsRequest) returns (ListMemoRelationsResponse) { + option (google.api.http) = {get: "/api/v1/{name=memos/*}/relations"}; + option (google.api.method_signature) = "name"; + } + // CreateMemoComment creates a comment for a memo. + rpc CreateMemoComment(CreateMemoCommentRequest) returns (Memo) { + option (google.api.http) = { + post: "/api/v1/{name=memos/*}/comments" + body: "comment" + }; + option (google.api.method_signature) = "name,comment"; + } + // ListMemoComments lists comments for a memo. + rpc ListMemoComments(ListMemoCommentsRequest) returns (ListMemoCommentsResponse) { + option (google.api.http) = {get: "/api/v1/{name=memos/*}/comments"}; + option (google.api.method_signature) = "name"; + } + // ListMemoReactions lists reactions for a memo. + rpc ListMemoReactions(ListMemoReactionsRequest) returns (ListMemoReactionsResponse) { + option (google.api.http) = {get: "/api/v1/{name=memos/*}/reactions"}; + option (google.api.method_signature) = "name"; + } + // UpsertMemoReaction upserts a reaction for a memo. + rpc UpsertMemoReaction(UpsertMemoReactionRequest) returns (Reaction) { + option (google.api.http) = { + post: "/api/v1/{name=memos/*}/reactions" + body: "*" + }; + option (google.api.method_signature) = "name"; + } + // DeleteMemoReaction deletes a reaction for a memo. + rpc DeleteMemoReaction(DeleteMemoReactionRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=memos/*/reactions/*}"}; + option (google.api.method_signature) = "name"; + } + // CreateMemoShare creates a share link for a memo. Requires authentication as the memo creator. + rpc CreateMemoShare(CreateMemoShareRequest) returns (MemoShare) { + option (google.api.http) = { + post: "/api/v1/{parent=memos/*}/shares" + body: "memo_share" + }; + option (google.api.method_signature) = "parent,memo_share"; + } + // ListMemoShares lists all share links for a memo. Requires authentication as the memo creator. + rpc ListMemoShares(ListMemoSharesRequest) returns (ListMemoSharesResponse) { + option (google.api.http) = {get: "/api/v1/{parent=memos/*}/shares"}; + option (google.api.method_signature) = "parent"; + } + // DeleteMemoShare revokes a share link. Requires authentication as the memo creator. + rpc DeleteMemoShare(DeleteMemoShareRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=memos/*/shares/*}"}; + option (google.api.method_signature) = "name"; + } + // GetMemoByShare resolves a share token to its memo. No authentication required. + // Returns NOT_FOUND if the token is invalid or expired. + rpc GetMemoByShare(GetMemoByShareRequest) returns (Memo) { + option (google.api.http) = {get: "/api/v1/shares/{share_id}"}; + } +} + +enum Visibility { + VISIBILITY_UNSPECIFIED = 0; + PRIVATE = 1; + PROTECTED = 2; + PUBLIC = 3; +} + +message Reaction { + option (google.api.resource) = { + type: "memos.api.v1/Reaction" + pattern: "memos/{memo}/reactions/{reaction}" + name_field: "name" + singular: "reaction" + plural: "reactions" + }; + + // The resource name of the reaction. + // Format: memos/{memo}/reactions/{reaction} + string name = 1 [ + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.field_behavior) = IDENTIFIER + ]; + + // The resource name of the creator. + // Format: users/{user} + string creator = 2 [ + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + // The resource name of the content. + // For memo reactions, this should be the memo's resource name. + // Format: memos/{memo} + string content_id = 3 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Required. The type of reaction (e.g., "👍", "❤️", "😄"). + string reaction_type = 4 [(google.api.field_behavior) = REQUIRED]; + + // Output only. The creation timestamp. + google.protobuf.Timestamp create_time = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; +} + +message Memo { + option (google.api.resource) = { + type: "memos.api.v1/Memo" + pattern: "memos/{memo}" + name_field: "name" + singular: "memo" + plural: "memos" + }; + + // The resource name of the memo. + // Format: memos/{memo}, memo is the user defined id or uuid. + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // The state of the memo. + State state = 2 [(google.api.field_behavior) = REQUIRED]; + + // The name of the creator. + // Format: users/{user} + string creator = 3 [ + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + // The creation timestamp. + // If not set on creation, the server will set it to the current time. + google.protobuf.Timestamp create_time = 4 [(google.api.field_behavior) = OPTIONAL]; + + // The last update timestamp. + // If not set on creation, the server will set it to the current time. + google.protobuf.Timestamp update_time = 5 [(google.api.field_behavior) = OPTIONAL]; + + // The display timestamp of the memo. + google.protobuf.Timestamp display_time = 6 [(google.api.field_behavior) = OPTIONAL]; + + // Required. The content of the memo in Markdown format. + string content = 7 [(google.api.field_behavior) = REQUIRED]; + + // The visibility of the memo. + Visibility visibility = 9 [(google.api.field_behavior) = REQUIRED]; + + // Output only. The tags extracted from the content. + repeated string tags = 10 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Whether the memo is pinned. + bool pinned = 11 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The attachments of the memo. + repeated Attachment attachments = 12 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The relations of the memo. + repeated MemoRelation relations = 13 [(google.api.field_behavior) = OPTIONAL]; + + // Output only. The reactions to the memo. + repeated Reaction reactions = 14 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The computed properties of the memo. + Property property = 15 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The name of the parent memo. + // Format: memos/{memo} + optional string parent = 16 [ + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Output only. The snippet of the memo content. Plain text only. + string snippet = 17 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Optional. The location of the memo. + optional Location location = 18 [(google.api.field_behavior) = OPTIONAL]; + + // Computed properties of a memo. + message Property { + bool has_link = 1; + bool has_task_list = 2; + bool has_code = 3; + bool has_incomplete_tasks = 4; + // The title extracted from the first H1 heading, if present. + string title = 5; + } +} + +message Location { + // A placeholder text for the location. + string placeholder = 1 [(google.api.field_behavior) = OPTIONAL]; + + // The latitude of the location. + double latitude = 2 [(google.api.field_behavior) = OPTIONAL]; + + // The longitude of the location. + double longitude = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message CreateMemoRequest { + // Required. The memo to create. + Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; + + // Optional. The memo ID to use for this memo. + // If empty, a unique ID will be generated. + string memo_id = 2 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListMemosRequest { + // Optional. The maximum number of memos to return. + // The service may return fewer than this value. + // If unspecified, at most 50 memos will be returned. + // The maximum value is 1000; values above 1000 will be coerced to 1000. + int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token, received from a previous `ListMemos` call. + // Provide this to retrieve the subsequent page. + string page_token = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The state of the memos to list. + // Default to `NORMAL`. Set to `ARCHIVED` to list archived memos. + State state = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The order to sort results by. + // Default to "display_time desc". + // Supports comma-separated list of fields following AIP-132. + // Example: "pinned desc, display_time desc" or "create_time asc" + // Supported fields: pinned, display_time, create_time, update_time, name + string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. Filter to apply to the list results. + // Filter is a CEL expression to filter memos. + // Refer to `Shortcut.filter`. + string filter = 5 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. If true, show deleted memos in the response. + bool show_deleted = 6 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListMemosResponse { + // The list of memos. + repeated Memo memos = 1; + + // A token that can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +message GetMemoRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; +} + +message UpdateMemoRequest { + // Required. The memo to update. + // The `name` field is required. + Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The list of fields to update. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message DeleteMemoRequest { + // Required. The resource name of the memo to delete. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Optional. If set to true, the memo will be deleted even if it has associated data. + bool force = 2 [(google.api.field_behavior) = OPTIONAL]; +} + +message SetMemoAttachmentsRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Required. The attachments to set for the memo. + repeated Attachment attachments = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message ListMemoAttachmentsRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Optional. The maximum number of attachments to return. + int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token for pagination. + string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListMemoAttachmentsResponse { + // The list of attachments. + repeated Attachment attachments = 1; + + // A token for the next page of results. + string next_page_token = 2; +} + +message MemoRelation { + // The memo in the relation. + Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; + + // The related memo. + Memo related_memo = 2 [(google.api.field_behavior) = REQUIRED]; + + // The type of the relation. + enum Type { + TYPE_UNSPECIFIED = 0; + REFERENCE = 1; + COMMENT = 2; + } + Type type = 3 [(google.api.field_behavior) = REQUIRED]; + + // Memo reference in relations. + message Memo { + // The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Output only. The snippet of the memo content. Plain text only. + string snippet = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; + } +} + +message SetMemoRelationsRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Required. The relations to set for the memo. + repeated MemoRelation relations = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message ListMemoRelationsRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Optional. The maximum number of relations to return. + int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token for pagination. + string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListMemoRelationsResponse { + // The list of relations. + repeated MemoRelation relations = 1; + + // A token for the next page of results. + string next_page_token = 2; +} + +message CreateMemoCommentRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Required. The comment to create. + Memo comment = 2 [(google.api.field_behavior) = REQUIRED]; + + // Optional. The comment ID to use. + string comment_id = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListMemoCommentsRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Optional. The maximum number of comments to return. + int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token for pagination. + string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The order to sort results by. + string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListMemoCommentsResponse { + // The list of comment memos. + repeated Memo memos = 1; + + // A token for the next page of results. + string next_page_token = 2; + + // The total count of comments. + int32 total_size = 3; +} + +message ListMemoReactionsRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Optional. The maximum number of reactions to return. + int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token for pagination. + string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListMemoReactionsResponse { + // The list of reactions. + repeated Reaction reactions = 1; + + // A token for the next page of results. + string next_page_token = 2; + + // The total count of reactions. + int32 total_size = 3; +} + +message UpsertMemoReactionRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Required. The reaction to upsert. + Reaction reaction = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message DeleteMemoReactionRequest { + // Required. The resource name of the reaction to delete. + // Format: memos/{memo}/reactions/{reaction} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Reaction"} + ]; +} + +// MemoShare is an access grant that permits read-only access to a memo via an opaque bearer token. +message MemoShare { + option (google.api.resource) = { + type: "memos.api.v1/MemoShare" + pattern: "memos/{memo}/shares/{share}" + singular: "share" + plural: "shares" + }; + + // The resource name of the share. Format: memos/{memo}/shares/{share} + // The {share} segment is the opaque token used in the share URL. + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // Output only. When this share link was created. + google.protobuf.Timestamp create_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Optional. When set, the share link stops working after this time. + // If unset, the link never expires. + optional google.protobuf.Timestamp expire_time = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message CreateMemoShareRequest { + // Required. The resource name of the memo to share. + // Format: memos/{memo} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; + + // Required. The share to create. + MemoShare memo_share = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message ListMemoSharesRequest { + // Required. The resource name of the memo. + // Format: memos/{memo} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Memo"} + ]; +} + +message ListMemoSharesResponse { + // The list of share links. + repeated MemoShare memo_shares = 1; +} + +message DeleteMemoShareRequest { + // Required. The resource name of the share to delete. + // Format: memos/{memo}/shares/{share} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/MemoShare"} + ]; +} + +message GetMemoByShareRequest { + // Required. The share token extracted from the share URL (/s/{share_id}). + string share_id = 1 [(google.api.field_behavior) = REQUIRED]; +} diff --git a/proto/api/v1/shortcut_service.proto b/proto/api/v1/shortcut_service.proto index 1201060e5..7ebb87807 100644 --- a/proto/api/v1/shortcut_service.proto +++ b/proto/api/v1/shortcut_service.proto @@ -1,124 +1,124 @@ -syntax = "proto3"; - -package memos.api.v1; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/field_mask.proto"; - -option go_package = "gen/api/v1"; - -service ShortcutService { - // ListShortcuts returns a list of shortcuts for a user. - rpc ListShortcuts(ListShortcutsRequest) returns (ListShortcutsResponse) { - option (google.api.http) = {get: "/api/v1/{parent=users/*}/shortcuts"}; - option (google.api.method_signature) = "parent"; - } - - // GetShortcut gets a shortcut by name. - rpc GetShortcut(GetShortcutRequest) returns (Shortcut) { - option (google.api.http) = {get: "/api/v1/{name=users/*/shortcuts/*}"}; - option (google.api.method_signature) = "name"; - } - - // CreateShortcut creates a new shortcut for a user. - rpc CreateShortcut(CreateShortcutRequest) returns (Shortcut) { - option (google.api.http) = { - post: "/api/v1/{parent=users/*}/shortcuts" - body: "shortcut" - }; - option (google.api.method_signature) = "parent,shortcut"; - } - - // UpdateShortcut updates a shortcut for a user. - rpc UpdateShortcut(UpdateShortcutRequest) returns (Shortcut) { - option (google.api.http) = { - patch: "/api/v1/{shortcut.name=users/*/shortcuts/*}" - body: "shortcut" - }; - option (google.api.method_signature) = "shortcut,update_mask"; - } - - // DeleteShortcut deletes a shortcut for a user. - rpc DeleteShortcut(DeleteShortcutRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=users/*/shortcuts/*}"}; - option (google.api.method_signature) = "name"; - } -} - -message Shortcut { - option (google.api.resource) = { - type: "memos.api.v1/Shortcut" - pattern: "users/{user}/shortcuts/{shortcut}" - singular: "shortcut" - plural: "shortcuts" - }; - - // The resource name of the shortcut. - // Format: users/{user}/shortcuts/{shortcut} - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // The title of the shortcut. - string title = 2 [(google.api.field_behavior) = REQUIRED]; - - // The filter expression for the shortcut. - string filter = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListShortcutsRequest { - // Required. The parent resource where shortcuts are listed. - // Format: users/{user} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {child_type: "memos.api.v1/Shortcut"} - ]; -} - -message ListShortcutsResponse { - // The list of shortcuts. - repeated Shortcut shortcuts = 1; -} - -message GetShortcutRequest { - // Required. The resource name of the shortcut to retrieve. - // Format: users/{user}/shortcuts/{shortcut} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Shortcut"} - ]; -} - -message CreateShortcutRequest { - // Required. The parent resource where this shortcut will be created. - // Format: users/{user} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {child_type: "memos.api.v1/Shortcut"} - ]; - - // Required. The shortcut to create. - Shortcut shortcut = 2 [(google.api.field_behavior) = REQUIRED]; - - // Optional. If set, validate the request, but do not actually create the shortcut. - bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message UpdateShortcutRequest { - // Required. The shortcut resource which replaces the resource on the server. - Shortcut shortcut = 1 [(google.api.field_behavior) = REQUIRED]; - - // Optional. The list of fields to update. - google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL]; -} - -message DeleteShortcutRequest { - // Required. The resource name of the shortcut to delete. - // Format: users/{user}/shortcuts/{shortcut} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/Shortcut"} - ]; -} +syntax = "proto3"; + +package memos.api.v1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; + +option go_package = "gen/api/v1"; + +service ShortcutService { + // ListShortcuts returns a list of shortcuts for a user. + rpc ListShortcuts(ListShortcutsRequest) returns (ListShortcutsResponse) { + option (google.api.http) = {get: "/api/v1/{parent=users/*}/shortcuts"}; + option (google.api.method_signature) = "parent"; + } + + // GetShortcut gets a shortcut by name. + rpc GetShortcut(GetShortcutRequest) returns (Shortcut) { + option (google.api.http) = {get: "/api/v1/{name=users/*/shortcuts/*}"}; + option (google.api.method_signature) = "name"; + } + + // CreateShortcut creates a new shortcut for a user. + rpc CreateShortcut(CreateShortcutRequest) returns (Shortcut) { + option (google.api.http) = { + post: "/api/v1/{parent=users/*}/shortcuts" + body: "shortcut" + }; + option (google.api.method_signature) = "parent,shortcut"; + } + + // UpdateShortcut updates a shortcut for a user. + rpc UpdateShortcut(UpdateShortcutRequest) returns (Shortcut) { + option (google.api.http) = { + patch: "/api/v1/{shortcut.name=users/*/shortcuts/*}" + body: "shortcut" + }; + option (google.api.method_signature) = "shortcut,update_mask"; + } + + // DeleteShortcut deletes a shortcut for a user. + rpc DeleteShortcut(DeleteShortcutRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=users/*/shortcuts/*}"}; + option (google.api.method_signature) = "name"; + } +} + +message Shortcut { + option (google.api.resource) = { + type: "memos.api.v1/Shortcut" + pattern: "users/{user}/shortcuts/{shortcut}" + singular: "shortcut" + plural: "shortcuts" + }; + + // The resource name of the shortcut. + // Format: users/{user}/shortcuts/{shortcut} + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // The title of the shortcut. + string title = 2 [(google.api.field_behavior) = REQUIRED]; + + // The filter expression for the shortcut. + string filter = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListShortcutsRequest { + // Required. The parent resource where shortcuts are listed. + // Format: users/{user} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {child_type: "memos.api.v1/Shortcut"} + ]; +} + +message ListShortcutsResponse { + // The list of shortcuts. + repeated Shortcut shortcuts = 1; +} + +message GetShortcutRequest { + // Required. The resource name of the shortcut to retrieve. + // Format: users/{user}/shortcuts/{shortcut} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Shortcut"} + ]; +} + +message CreateShortcutRequest { + // Required. The parent resource where this shortcut will be created. + // Format: users/{user} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {child_type: "memos.api.v1/Shortcut"} + ]; + + // Required. The shortcut to create. + Shortcut shortcut = 2 [(google.api.field_behavior) = REQUIRED]; + + // Optional. If set, validate the request, but do not actually create the shortcut. + bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message UpdateShortcutRequest { + // Required. The shortcut resource which replaces the resource on the server. + Shortcut shortcut = 1 [(google.api.field_behavior) = REQUIRED]; + + // Optional. The list of fields to update. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL]; +} + +message DeleteShortcutRequest { + // Required. The resource name of the shortcut to delete. + // Format: users/{user}/shortcuts/{shortcut} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/Shortcut"} + ]; +} diff --git a/proto/api/v1/user_service.proto b/proto/api/v1/user_service.proto index b585379ca..e30a5cccd 100644 --- a/proto/api/v1/user_service.proto +++ b/proto/api/v1/user_service.proto @@ -1,684 +1,684 @@ -syntax = "proto3"; - -package memos.api.v1; - -import "api/v1/common.proto"; -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/field_mask.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "gen/api/v1"; - -service UserService { - // ListUsers returns a list of users. - rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) { - option (google.api.http) = {get: "/api/v1/users"}; - } - - // GetUser gets a user by ID or username. - // Supports both numeric IDs and username strings: - // - users/{id} (e.g., users/101) - // - users/{username} (e.g., users/steven) - rpc GetUser(GetUserRequest) returns (User) { - option (google.api.http) = {get: "/api/v1/{name=users/*}"}; - option (google.api.method_signature) = "name"; - } - - // CreateUser creates a new user. - rpc CreateUser(CreateUserRequest) returns (User) { - option (google.api.http) = { - post: "/api/v1/users" - body: "user" - }; - option (google.api.method_signature) = "user"; - } - - // UpdateUser updates a user. - rpc UpdateUser(UpdateUserRequest) returns (User) { - option (google.api.http) = { - patch: "/api/v1/{user.name=users/*}" - body: "user" - }; - option (google.api.method_signature) = "user,update_mask"; - } - - // DeleteUser deletes a user. - rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=users/*}"}; - option (google.api.method_signature) = "name"; - } - - // ListAllUserStats returns statistics for all users. - rpc ListAllUserStats(ListAllUserStatsRequest) returns (ListAllUserStatsResponse) { - option (google.api.http) = {get: "/api/v1/users:stats"}; - } - - // GetUserStats returns statistics for a specific user. - rpc GetUserStats(GetUserStatsRequest) returns (UserStats) { - option (google.api.http) = {get: "/api/v1/{name=users/*}:getStats"}; - option (google.api.method_signature) = "name"; - } - - // GetUserSetting returns the user setting. - rpc GetUserSetting(GetUserSettingRequest) returns (UserSetting) { - option (google.api.http) = {get: "/api/v1/{name=users/*/settings/*}"}; - option (google.api.method_signature) = "name"; - } - - // UpdateUserSetting updates the user setting. - rpc UpdateUserSetting(UpdateUserSettingRequest) returns (UserSetting) { - option (google.api.http) = { - patch: "/api/v1/{setting.name=users/*/settings/*}" - body: "setting" - }; - option (google.api.method_signature) = "setting,update_mask"; - } - - // ListUserSettings returns a list of user settings. - rpc ListUserSettings(ListUserSettingsRequest) returns (ListUserSettingsResponse) { - option (google.api.http) = {get: "/api/v1/{parent=users/*}/settings"}; - option (google.api.method_signature) = "parent"; - } - - // ListPersonalAccessTokens returns a list of Personal Access Tokens (PATs) for a user. - // PATs are long-lived tokens for API/script access, distinct from short-lived JWT access tokens. - rpc ListPersonalAccessTokens(ListPersonalAccessTokensRequest) returns (ListPersonalAccessTokensResponse) { - option (google.api.http) = {get: "/api/v1/{parent=users/*}/personalAccessTokens"}; - option (google.api.method_signature) = "parent"; - } - - // CreatePersonalAccessToken creates a new Personal Access Token for a user. - // The token value is only returned once upon creation. - rpc CreatePersonalAccessToken(CreatePersonalAccessTokenRequest) returns (CreatePersonalAccessTokenResponse) { - option (google.api.http) = { - post: "/api/v1/{parent=users/*}/personalAccessTokens" - body: "*" - }; - } - - // DeletePersonalAccessToken deletes a Personal Access Token. - rpc DeletePersonalAccessToken(DeletePersonalAccessTokenRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=users/*/personalAccessTokens/*}"}; - 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"}; - option (google.api.method_signature) = "parent"; - } - - // CreateUserWebhook creates a new webhook for a user. - rpc CreateUserWebhook(CreateUserWebhookRequest) returns (UserWebhook) { - option (google.api.http) = { - post: "/api/v1/{parent=users/*}/webhooks" - body: "webhook" - }; - option (google.api.method_signature) = "parent,webhook"; - } - - // UpdateUserWebhook updates an existing webhook for a user. - rpc UpdateUserWebhook(UpdateUserWebhookRequest) returns (UserWebhook) { - option (google.api.http) = { - patch: "/api/v1/{webhook.name=users/*/webhooks/*}" - body: "webhook" - }; - option (google.api.method_signature) = "webhook,update_mask"; - } - - // DeleteUserWebhook deletes a webhook for a user. - rpc DeleteUserWebhook(DeleteUserWebhookRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=users/*/webhooks/*}"}; - option (google.api.method_signature) = "name"; - } - - // ListUserNotifications lists notifications for a user. - rpc ListUserNotifications(ListUserNotificationsRequest) returns (ListUserNotificationsResponse) { - option (google.api.http) = {get: "/api/v1/{parent=users/*}/notifications"}; - option (google.api.method_signature) = "parent"; - } - - // UpdateUserNotification updates a notification. - rpc UpdateUserNotification(UpdateUserNotificationRequest) returns (UserNotification) { - option (google.api.http) = { - patch: "/api/v1/{notification.name=users/*/notifications/*}" - body: "notification" - }; - option (google.api.method_signature) = "notification,update_mask"; - } - - // DeleteUserNotification deletes a notification. - rpc DeleteUserNotification(DeleteUserNotificationRequest) returns (google.protobuf.Empty) { - option (google.api.http) = {delete: "/api/v1/{name=users/*/notifications/*}"}; - option (google.api.method_signature) = "name"; - } -} - -message User { - option (google.api.resource) = { - type: "memos.api.v1/User" - pattern: "users/{user}" - name_field: "name" - singular: "user" - plural: "users" - }; - - // The resource name of the user. - // Format: users/{user} - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // The role of the user. - Role role = 2 [(google.api.field_behavior) = REQUIRED]; - - // Required. The unique username for login. - string username = 3 [(google.api.field_behavior) = REQUIRED]; - - // Optional. The email address of the user. - string email = 4 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The display name of the user. - string display_name = 5 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The avatar URL of the user. - string avatar_url = 6 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. The description of the user. - string description = 7 [(google.api.field_behavior) = OPTIONAL]; - - // Input only. The password for the user. - string password = 8 [(google.api.field_behavior) = INPUT_ONLY]; - - // The state of the user. - State state = 9 [(google.api.field_behavior) = REQUIRED]; - - // Output only. The creation timestamp. - google.protobuf.Timestamp create_time = 10 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Output only. The last update timestamp. - google.protobuf.Timestamp update_time = 11 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // User role enumeration. - enum Role { - ROLE_UNSPECIFIED = 0; - // Admin role with system access. - ADMIN = 2; - // User role with limited access. - USER = 3; - } -} - -message ListUsersRequest { - // Optional. The maximum number of users to return. - // The service may return fewer than this value. - // If unspecified, at most 50 users will be returned. - // The maximum value is 1000; values above 1000 will be coerced to 1000. - int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token, received from a previous `ListUsers` call. - // Provide this to retrieve the subsequent page. - string page_token = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. Filter to apply to the list results. - // Example: "username == 'steven'" - // Supported operators: == - // Supported fields: username - string filter = 3 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. If true, show deleted users in the response. - bool show_deleted = 4 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListUsersResponse { - // The list of users. - repeated User users = 1; - - // A token that can be sent as `page_token` to retrieve the next page. - // If this field is omitted, there are no subsequent pages. - string next_page_token = 2; - - // The total count of users (may be approximate). - int32 total_size = 3; -} - -message GetUserRequest { - // Required. The resource name of the user. - // Supports both numeric IDs and username strings: - // - users/{id} (e.g., users/101) - // - users/{username} (e.g., users/steven) - // Format: users/{id_or_username} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - // Optional. The fields to return in the response. - // If not specified, all fields are returned. - google.protobuf.FieldMask read_mask = 2 [(google.api.field_behavior) = OPTIONAL]; -} - -message CreateUserRequest { - // Required. The user to create. - User user = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.field_behavior) = INPUT_ONLY - ]; - - // Optional. The user ID to use for this user. - // If empty, a unique ID will be generated. - // Must match the pattern [a-z0-9-]+ - string user_id = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. If set, validate the request but don't actually create the user. - bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. An idempotency token that can be used to ensure that multiple - // requests to create a user have the same result. - string request_id = 4 [(google.api.field_behavior) = OPTIONAL]; -} - -message UpdateUserRequest { - // Required. The user to update. - User user = 1 [(google.api.field_behavior) = REQUIRED]; - - // Required. The list of fields to update. - google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; - - // Optional. If set to true, allows updating sensitive fields. - bool allow_missing = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message DeleteUserRequest { - // Required. The resource name of the user to delete. - // Format: users/{user} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - // Optional. If set to true, the user will be deleted even if they have associated data. - bool force = 2 [(google.api.field_behavior) = OPTIONAL]; -} - -// User statistics messages -message UserStats { - option (google.api.resource) = { - type: "memos.api.v1/UserStats" - pattern: "users/{user}" - singular: "userStats" - plural: "userStats" - }; - - // The resource name of the user whose stats these are. - // Format: users/{user} - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // The timestamps when the memos were displayed. - repeated google.protobuf.Timestamp memo_display_timestamps = 2; - - // The stats of memo types. - MemoTypeStats memo_type_stats = 3; - - // The count of tags. - map tag_count = 4; - - // The pinned memos of the user. - repeated string pinned_memos = 5; - - // Total memo count. - int32 total_memo_count = 6; - - // Memo type statistics. - message MemoTypeStats { - int32 link_count = 1; - int32 code_count = 2; - int32 todo_count = 3; - int32 undo_count = 4; - } -} - -message GetUserStatsRequest { - // Required. The resource name of the user. - // Format: users/{user} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; -} - -message ListAllUserStatsRequest { - // This endpoint doesn't take any parameters. -} - -message ListAllUserStatsResponse { - // The list of user statistics. - repeated UserStats stats = 1; -} - -// User settings message -message UserSetting { - option (google.api.resource) = { - type: "memos.api.v1/UserSetting" - pattern: "users/{user}/settings/{setting}" - singular: "userSetting" - plural: "userSettings" - }; - - // The name of the user setting. - // Format: users/{user}/settings/{setting}, {setting} is the key for the setting. - // For example, "users/123/settings/GENERAL" for general settings. - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - oneof value { - GeneralSetting general_setting = 2; - WebhooksSetting webhooks_setting = 5; - } - - // Enumeration of user setting keys. - enum Key { - KEY_UNSPECIFIED = 0; - // GENERAL is the key for general user settings. - GENERAL = 1; - // WEBHOOKS is the key for user webhooks. - WEBHOOKS = 4; - } - - // General user settings configuration. - message GeneralSetting { - // The preferred locale of the user. - string locale = 1 [(google.api.field_behavior) = OPTIONAL]; - // The default visibility of the memo. - string memo_visibility = 3 [(google.api.field_behavior) = OPTIONAL]; - // The preferred theme of the user. - // This references a CSS file in the web/public/themes/ directory. - // If not set, the default theme will be used. - string theme = 4 [(google.api.field_behavior) = OPTIONAL]; - } - - // User webhooks configuration. - message WebhooksSetting { - // List of user webhooks. - repeated UserWebhook webhooks = 1; - } -} - -message GetUserSettingRequest { - // Required. The resource name of the user setting. - // Format: users/{user}/settings/{setting} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/UserSetting"} - ]; -} - -message UpdateUserSettingRequest { - // Required. The user setting to update. - UserSetting setting = 1 [(google.api.field_behavior) = REQUIRED]; - - // Required. The list of fields to update. - google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for ListUserSettings method. -message ListUserSettingsRequest { - // Required. The parent resource whose settings will be listed. - // Format: users/{user} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - // Optional. The maximum number of settings to return. - // The service may return fewer than this value. - // If unspecified, at most 50 settings will be returned. - // The maximum value is 1000; values above 1000 will be coerced to 1000. - int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token, received from a previous `ListUserSettings` call. - // Provide this to retrieve the subsequent page. - string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -// Response message for ListUserSettings method. -message ListUserSettingsResponse { - // The list of user settings. - repeated UserSetting settings = 1; - - // A token that can be sent as `page_token` to retrieve the next page. - // If this field is omitted, there are no subsequent pages. - string next_page_token = 2; - - // The total count of settings (may be approximate). - int32 total_size = 3; -} - -// PersonalAccessToken represents a long-lived token for API/script access. -// PATs are distinct from short-lived JWT access tokens used for session authentication. -message PersonalAccessToken { - option (google.api.resource) = { - type: "memos.api.v1/PersonalAccessToken" - pattern: "users/{user}/personalAccessTokens/{personal_access_token}" - singular: "personalAccessToken" - plural: "personalAccessTokens" - }; - - // The resource name of the personal access token. - // Format: users/{user}/personalAccessTokens/{personal_access_token} - string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - - // The description of the token. - string description = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Output only. The creation timestamp. - google.protobuf.Timestamp created_at = 3 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // Optional. The expiration timestamp. - google.protobuf.Timestamp expires_at = 4 [(google.api.field_behavior) = OPTIONAL]; - - // Output only. The last used timestamp. - google.protobuf.Timestamp last_used_at = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; -} - -message ListPersonalAccessTokensRequest { - // Required. The parent resource whose personal access tokens will be listed. - // Format: users/{user} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - // Optional. The maximum number of tokens to return. - int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. A page token for pagination. - string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListPersonalAccessTokensResponse { - // The list of personal access tokens. - repeated PersonalAccessToken personal_access_tokens = 1; - - // A token for the next page of results. - string next_page_token = 2; - - // The total count of personal access tokens. - int32 total_size = 3; -} - -message CreatePersonalAccessTokenRequest { - // Required. The parent resource where this token will be created. - // Format: users/{user} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - // Optional. Description of the personal access token. - string description = 2 [(google.api.field_behavior) = OPTIONAL]; - - // Optional. Expiration duration in days (0 = never expires). - int32 expires_in_days = 3 [(google.api.field_behavior) = OPTIONAL]; -} - -message CreatePersonalAccessTokenResponse { - // The personal access token metadata. - PersonalAccessToken personal_access_token = 1; - - // The actual token value - only returned on creation. - // This is the only time the token value will be visible. - string token = 2; -} - -message DeletePersonalAccessTokenRequest { - // Required. The resource name of the personal access token to delete. - // Format: users/{user}/personalAccessTokens/{personal_access_token} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/PersonalAccessToken"} - ]; -} - -// UserWebhook represents a webhook owned by a user. -message UserWebhook { - // The name of the webhook. - // Format: users/{user}/webhooks/{webhook} - string name = 1; - - // The URL to send the webhook to. - string url = 2; - - // Optional. Human-readable name for the webhook. - string display_name = 3; - - // The creation time of the webhook. - google.protobuf.Timestamp create_time = 4 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // The last update time of the webhook. - google.protobuf.Timestamp update_time = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; -} - -message ListUserWebhooksRequest { - // The parent user resource. - // Format: users/{user} - string parent = 1 [(google.api.field_behavior) = REQUIRED]; -} - -message ListUserWebhooksResponse { - // The list of webhooks. - repeated UserWebhook webhooks = 1; -} - -message CreateUserWebhookRequest { - // The parent user resource. - // Format: users/{user} - string parent = 1 [(google.api.field_behavior) = REQUIRED]; - - // The webhook to create. - UserWebhook webhook = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message UpdateUserWebhookRequest { - // The webhook to update. - UserWebhook webhook = 1 [(google.api.field_behavior) = REQUIRED]; - - // The list of fields to update. - google.protobuf.FieldMask update_mask = 2; -} - -message DeleteUserWebhookRequest { - // The name of the webhook to delete. - // Format: users/{user}/webhooks/{webhook} - string name = 1 [(google.api.field_behavior) = REQUIRED]; -} - -message UserNotification { - option (google.api.resource) = { - type: "memos.api.v1/UserNotification" - pattern: "users/{user}/notifications/{notification}" - name_field: "name" - singular: "notification" - plural: "notifications" - }; - - // The resource name of the notification. - // Format: users/{user}/notifications/{notification} - string name = 1 [ - (google.api.field_behavior) = OUTPUT_ONLY, - (google.api.field_behavior) = IDENTIFIER - ]; - - // The sender of the notification. - // Format: users/{user} - string sender = 2 [ - (google.api.field_behavior) = OUTPUT_ONLY, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - // The status of the notification. - Status status = 3 [(google.api.field_behavior) = OPTIONAL]; - - // The creation timestamp. - google.protobuf.Timestamp create_time = 4 [(google.api.field_behavior) = OUTPUT_ONLY]; - - // The type of the notification. - Type type = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; - - oneof payload { - MemoCommentPayload memo_comment = 6 [(google.api.field_behavior) = OUTPUT_ONLY]; - } - - message MemoCommentPayload { - // The memo name of comment. - // Format: memos/{memo} - string memo = 1; - - // The name of related memo. - // Format: memos/{memo} - string related_memo = 2; - } - - enum Status { - STATUS_UNSPECIFIED = 0; - UNREAD = 1; - ARCHIVED = 2; - } - - enum Type { - TYPE_UNSPECIFIED = 0; - MEMO_COMMENT = 1; - } -} - -message ListUserNotificationsRequest { - // The parent user resource. - // Format: users/{user} - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/User"} - ]; - - int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; - string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; - string filter = 4 [(google.api.field_behavior) = OPTIONAL]; -} - -message ListUserNotificationsResponse { - repeated UserNotification notifications = 1; - string next_page_token = 2; -} - -message UpdateUserNotificationRequest { - UserNotification notification = 1 [(google.api.field_behavior) = REQUIRED]; - google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message DeleteUserNotificationRequest { - // Format: users/{user}/notifications/{notification} - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = {type: "memos.api.v1/UserNotification"} - ]; -} +syntax = "proto3"; + +package memos.api.v1; + +import "api/v1/common.proto"; +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "gen/api/v1"; + +service UserService { + // ListUsers returns a list of users. + rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) { + option (google.api.http) = {get: "/api/v1/users"}; + } + + // GetUser gets a user by ID or username. + // Supports both numeric IDs and username strings: + // - users/{id} (e.g., users/101) + // - users/{username} (e.g., users/steven) + rpc GetUser(GetUserRequest) returns (User) { + option (google.api.http) = {get: "/api/v1/{name=users/*}"}; + option (google.api.method_signature) = "name"; + } + + // CreateUser creates a new user. + rpc CreateUser(CreateUserRequest) returns (User) { + option (google.api.http) = { + post: "/api/v1/users" + body: "user" + }; + option (google.api.method_signature) = "user"; + } + + // UpdateUser updates a user. + rpc UpdateUser(UpdateUserRequest) returns (User) { + option (google.api.http) = { + patch: "/api/v1/{user.name=users/*}" + body: "user" + }; + option (google.api.method_signature) = "user,update_mask"; + } + + // DeleteUser deletes a user. + rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=users/*}"}; + option (google.api.method_signature) = "name"; + } + + // ListAllUserStats returns statistics for all users. + rpc ListAllUserStats(ListAllUserStatsRequest) returns (ListAllUserStatsResponse) { + option (google.api.http) = {get: "/api/v1/users:stats"}; + } + + // GetUserStats returns statistics for a specific user. + rpc GetUserStats(GetUserStatsRequest) returns (UserStats) { + option (google.api.http) = {get: "/api/v1/{name=users/*}:getStats"}; + option (google.api.method_signature) = "name"; + } + + // GetUserSetting returns the user setting. + rpc GetUserSetting(GetUserSettingRequest) returns (UserSetting) { + option (google.api.http) = {get: "/api/v1/{name=users/*/settings/*}"}; + option (google.api.method_signature) = "name"; + } + + // UpdateUserSetting updates the user setting. + rpc UpdateUserSetting(UpdateUserSettingRequest) returns (UserSetting) { + option (google.api.http) = { + patch: "/api/v1/{setting.name=users/*/settings/*}" + body: "setting" + }; + option (google.api.method_signature) = "setting,update_mask"; + } + + // ListUserSettings returns a list of user settings. + rpc ListUserSettings(ListUserSettingsRequest) returns (ListUserSettingsResponse) { + option (google.api.http) = {get: "/api/v1/{parent=users/*}/settings"}; + option (google.api.method_signature) = "parent"; + } + + // ListPersonalAccessTokens returns a list of Personal Access Tokens (PATs) for a user. + // PATs are long-lived tokens for API/script access, distinct from short-lived JWT access tokens. + rpc ListPersonalAccessTokens(ListPersonalAccessTokensRequest) returns (ListPersonalAccessTokensResponse) { + option (google.api.http) = {get: "/api/v1/{parent=users/*}/personalAccessTokens"}; + option (google.api.method_signature) = "parent"; + } + + // CreatePersonalAccessToken creates a new Personal Access Token for a user. + // The token value is only returned once upon creation. + rpc CreatePersonalAccessToken(CreatePersonalAccessTokenRequest) returns (CreatePersonalAccessTokenResponse) { + option (google.api.http) = { + post: "/api/v1/{parent=users/*}/personalAccessTokens" + body: "*" + }; + } + + // DeletePersonalAccessToken deletes a Personal Access Token. + rpc DeletePersonalAccessToken(DeletePersonalAccessTokenRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=users/*/personalAccessTokens/*}"}; + 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"}; + option (google.api.method_signature) = "parent"; + } + + // CreateUserWebhook creates a new webhook for a user. + rpc CreateUserWebhook(CreateUserWebhookRequest) returns (UserWebhook) { + option (google.api.http) = { + post: "/api/v1/{parent=users/*}/webhooks" + body: "webhook" + }; + option (google.api.method_signature) = "parent,webhook"; + } + + // UpdateUserWebhook updates an existing webhook for a user. + rpc UpdateUserWebhook(UpdateUserWebhookRequest) returns (UserWebhook) { + option (google.api.http) = { + patch: "/api/v1/{webhook.name=users/*/webhooks/*}" + body: "webhook" + }; + option (google.api.method_signature) = "webhook,update_mask"; + } + + // DeleteUserWebhook deletes a webhook for a user. + rpc DeleteUserWebhook(DeleteUserWebhookRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=users/*/webhooks/*}"}; + option (google.api.method_signature) = "name"; + } + + // ListUserNotifications lists notifications for a user. + rpc ListUserNotifications(ListUserNotificationsRequest) returns (ListUserNotificationsResponse) { + option (google.api.http) = {get: "/api/v1/{parent=users/*}/notifications"}; + option (google.api.method_signature) = "parent"; + } + + // UpdateUserNotification updates a notification. + rpc UpdateUserNotification(UpdateUserNotificationRequest) returns (UserNotification) { + option (google.api.http) = { + patch: "/api/v1/{notification.name=users/*/notifications/*}" + body: "notification" + }; + option (google.api.method_signature) = "notification,update_mask"; + } + + // DeleteUserNotification deletes a notification. + rpc DeleteUserNotification(DeleteUserNotificationRequest) returns (google.protobuf.Empty) { + option (google.api.http) = {delete: "/api/v1/{name=users/*/notifications/*}"}; + option (google.api.method_signature) = "name"; + } +} + +message User { + option (google.api.resource) = { + type: "memos.api.v1/User" + pattern: "users/{user}" + name_field: "name" + singular: "user" + plural: "users" + }; + + // The resource name of the user. + // Format: users/{user} + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // The role of the user. + Role role = 2 [(google.api.field_behavior) = REQUIRED]; + + // Required. The unique username for login. + string username = 3 [(google.api.field_behavior) = REQUIRED]; + + // Optional. The email address of the user. + string email = 4 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The display name of the user. + string display_name = 5 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The avatar URL of the user. + string avatar_url = 6 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The description of the user. + string description = 7 [(google.api.field_behavior) = OPTIONAL]; + + // Input only. The password for the user. + string password = 8 [(google.api.field_behavior) = INPUT_ONLY]; + + // The state of the user. + State state = 9 [(google.api.field_behavior) = REQUIRED]; + + // Output only. The creation timestamp. + google.protobuf.Timestamp create_time = 10 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The last update timestamp. + google.protobuf.Timestamp update_time = 11 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // User role enumeration. + enum Role { + ROLE_UNSPECIFIED = 0; + // Admin role with system access. + ADMIN = 2; + // User role with limited access. + USER = 3; + } +} + +message ListUsersRequest { + // Optional. The maximum number of users to return. + // The service may return fewer than this value. + // If unspecified, at most 50 users will be returned. + // The maximum value is 1000; values above 1000 will be coerced to 1000. + int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token, received from a previous `ListUsers` call. + // Provide this to retrieve the subsequent page. + string page_token = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. Filter to apply to the list results. + // Example: "username == 'steven'" + // Supported operators: == + // Supported fields: username + string filter = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. If true, show deleted users in the response. + bool show_deleted = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListUsersResponse { + // The list of users. + repeated User users = 1; + + // A token that can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; + + // The total count of users (may be approximate). + int32 total_size = 3; +} + +message GetUserRequest { + // Required. The resource name of the user. + // Supports both numeric IDs and username strings: + // - users/{id} (e.g., users/101) + // - users/{username} (e.g., users/steven) + // Format: users/{id_or_username} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + // Optional. The fields to return in the response. + // If not specified, all fields are returned. + google.protobuf.FieldMask read_mask = 2 [(google.api.field_behavior) = OPTIONAL]; +} + +message CreateUserRequest { + // Required. The user to create. + User user = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = INPUT_ONLY + ]; + + // Optional. The user ID to use for this user. + // If empty, a unique ID will be generated. + // Must match the pattern [a-z0-9-]+ + string user_id = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. If set, validate the request but don't actually create the user. + bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. An idempotency token that can be used to ensure that multiple + // requests to create a user have the same result. + string request_id = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +message UpdateUserRequest { + // Required. The user to update. + User user = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The list of fields to update. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; + + // Optional. If set to true, allows updating sensitive fields. + bool allow_missing = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message DeleteUserRequest { + // Required. The resource name of the user to delete. + // Format: users/{user} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + // Optional. If set to true, the user will be deleted even if they have associated data. + bool force = 2 [(google.api.field_behavior) = OPTIONAL]; +} + +// User statistics messages +message UserStats { + option (google.api.resource) = { + type: "memos.api.v1/UserStats" + pattern: "users/{user}" + singular: "userStats" + plural: "userStats" + }; + + // The resource name of the user whose stats these are. + // Format: users/{user} + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // The timestamps when the memos were displayed. + repeated google.protobuf.Timestamp memo_display_timestamps = 2; + + // The stats of memo types. + MemoTypeStats memo_type_stats = 3; + + // The count of tags. + map tag_count = 4; + + // The pinned memos of the user. + repeated string pinned_memos = 5; + + // Total memo count. + int32 total_memo_count = 6; + + // Memo type statistics. + message MemoTypeStats { + int32 link_count = 1; + int32 code_count = 2; + int32 todo_count = 3; + int32 undo_count = 4; + } +} + +message GetUserStatsRequest { + // Required. The resource name of the user. + // Format: users/{user} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; +} + +message ListAllUserStatsRequest { + // This endpoint doesn't take any parameters. +} + +message ListAllUserStatsResponse { + // The list of user statistics. + repeated UserStats stats = 1; +} + +// User settings message +message UserSetting { + option (google.api.resource) = { + type: "memos.api.v1/UserSetting" + pattern: "users/{user}/settings/{setting}" + singular: "userSetting" + plural: "userSettings" + }; + + // The name of the user setting. + // Format: users/{user}/settings/{setting}, {setting} is the key for the setting. + // For example, "users/123/settings/GENERAL" for general settings. + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + oneof value { + GeneralSetting general_setting = 2; + WebhooksSetting webhooks_setting = 5; + } + + // Enumeration of user setting keys. + enum Key { + KEY_UNSPECIFIED = 0; + // GENERAL is the key for general user settings. + GENERAL = 1; + // WEBHOOKS is the key for user webhooks. + WEBHOOKS = 4; + } + + // General user settings configuration. + message GeneralSetting { + // The preferred locale of the user. + string locale = 1 [(google.api.field_behavior) = OPTIONAL]; + // The default visibility of the memo. + string memo_visibility = 3 [(google.api.field_behavior) = OPTIONAL]; + // The preferred theme of the user. + // This references a CSS file in the web/public/themes/ directory. + // If not set, the default theme will be used. + string theme = 4 [(google.api.field_behavior) = OPTIONAL]; + } + + // User webhooks configuration. + message WebhooksSetting { + // List of user webhooks. + repeated UserWebhook webhooks = 1; + } +} + +message GetUserSettingRequest { + // Required. The resource name of the user setting. + // Format: users/{user}/settings/{setting} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/UserSetting"} + ]; +} + +message UpdateUserSettingRequest { + // Required. The user setting to update. + UserSetting setting = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The list of fields to update. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for ListUserSettings method. +message ListUserSettingsRequest { + // Required. The parent resource whose settings will be listed. + // Format: users/{user} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + // Optional. The maximum number of settings to return. + // The service may return fewer than this value. + // If unspecified, at most 50 settings will be returned. + // The maximum value is 1000; values above 1000 will be coerced to 1000. + int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token, received from a previous `ListUserSettings` call. + // Provide this to retrieve the subsequent page. + string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response message for ListUserSettings method. +message ListUserSettingsResponse { + // The list of user settings. + repeated UserSetting settings = 1; + + // A token that can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; + + // The total count of settings (may be approximate). + int32 total_size = 3; +} + +// PersonalAccessToken represents a long-lived token for API/script access. +// PATs are distinct from short-lived JWT access tokens used for session authentication. +message PersonalAccessToken { + option (google.api.resource) = { + type: "memos.api.v1/PersonalAccessToken" + pattern: "users/{user}/personalAccessTokens/{personal_access_token}" + singular: "personalAccessToken" + plural: "personalAccessTokens" + }; + + // The resource name of the personal access token. + // Format: users/{user}/personalAccessTokens/{personal_access_token} + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // The description of the token. + string description = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Output only. The creation timestamp. + google.protobuf.Timestamp created_at = 3 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Optional. The expiration timestamp. + google.protobuf.Timestamp expires_at = 4 [(google.api.field_behavior) = OPTIONAL]; + + // Output only. The last used timestamp. + google.protobuf.Timestamp last_used_at = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; +} + +message ListPersonalAccessTokensRequest { + // Required. The parent resource whose personal access tokens will be listed. + // Format: users/{user} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + // Optional. The maximum number of tokens to return. + int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. A page token for pagination. + string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListPersonalAccessTokensResponse { + // The list of personal access tokens. + repeated PersonalAccessToken personal_access_tokens = 1; + + // A token for the next page of results. + string next_page_token = 2; + + // The total count of personal access tokens. + int32 total_size = 3; +} + +message CreatePersonalAccessTokenRequest { + // Required. The parent resource where this token will be created. + // Format: users/{user} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + // Optional. Description of the personal access token. + string description = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. Expiration duration in days (0 = never expires). + int32 expires_in_days = 3 [(google.api.field_behavior) = OPTIONAL]; +} + +message CreatePersonalAccessTokenResponse { + // The personal access token metadata. + PersonalAccessToken personal_access_token = 1; + + // The actual token value - only returned on creation. + // This is the only time the token value will be visible. + string token = 2; +} + +message DeletePersonalAccessTokenRequest { + // Required. The resource name of the personal access token to delete. + // Format: users/{user}/personalAccessTokens/{personal_access_token} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/PersonalAccessToken"} + ]; +} + +// UserWebhook represents a webhook owned by a user. +message UserWebhook { + // The name of the webhook. + // Format: users/{user}/webhooks/{webhook} + string name = 1; + + // The URL to send the webhook to. + string url = 2; + + // Optional. Human-readable name for the webhook. + string display_name = 3; + + // The creation time of the webhook. + google.protobuf.Timestamp create_time = 4 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // The last update time of the webhook. + google.protobuf.Timestamp update_time = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; +} + +message ListUserWebhooksRequest { + // The parent user resource. + // Format: users/{user} + string parent = 1 [(google.api.field_behavior) = REQUIRED]; +} + +message ListUserWebhooksResponse { + // The list of webhooks. + repeated UserWebhook webhooks = 1; +} + +message CreateUserWebhookRequest { + // The parent user resource. + // Format: users/{user} + string parent = 1 [(google.api.field_behavior) = REQUIRED]; + + // The webhook to create. + UserWebhook webhook = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message UpdateUserWebhookRequest { + // The webhook to update. + UserWebhook webhook = 1 [(google.api.field_behavior) = REQUIRED]; + + // The list of fields to update. + google.protobuf.FieldMask update_mask = 2; +} + +message DeleteUserWebhookRequest { + // The name of the webhook to delete. + // Format: users/{user}/webhooks/{webhook} + string name = 1 [(google.api.field_behavior) = REQUIRED]; +} + +message UserNotification { + option (google.api.resource) = { + type: "memos.api.v1/UserNotification" + pattern: "users/{user}/notifications/{notification}" + name_field: "name" + singular: "notification" + plural: "notifications" + }; + + // The resource name of the notification. + // Format: users/{user}/notifications/{notification} + string name = 1 [ + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.field_behavior) = IDENTIFIER + ]; + + // The sender of the notification. + // Format: users/{user} + string sender = 2 [ + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + // The status of the notification. + Status status = 3 [(google.api.field_behavior) = OPTIONAL]; + + // The creation timestamp. + google.protobuf.Timestamp create_time = 4 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // The type of the notification. + Type type = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; + + oneof payload { + MemoCommentPayload memo_comment = 6 [(google.api.field_behavior) = OUTPUT_ONLY]; + } + + message MemoCommentPayload { + // The memo name of comment. + // Format: memos/{memo} + string memo = 1; + + // The name of related memo. + // Format: memos/{memo} + string related_memo = 2; + } + + enum Status { + STATUS_UNSPECIFIED = 0; + UNREAD = 1; + ARCHIVED = 2; + } + + enum Type { + TYPE_UNSPECIFIED = 0; + MEMO_COMMENT = 1; + } +} + +message ListUserNotificationsRequest { + // The parent user resource. + // Format: users/{user} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/User"} + ]; + + int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; + string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; + string filter = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +message ListUserNotificationsResponse { + repeated UserNotification notifications = 1; + string next_page_token = 2; +} + +message UpdateUserNotificationRequest { + UserNotification notification = 1 [(google.api.field_behavior) = REQUIRED]; + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message DeleteUserNotificationRequest { + // Format: users/{user}/notifications/{notification} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = {type: "memos.api.v1/UserNotification"} + ]; +} diff --git a/proto/store/attachment.proto b/proto/store/attachment.proto index 0161f4de8..018f854d2 100644 --- a/proto/store/attachment.proto +++ b/proto/store/attachment.proto @@ -1,33 +1,33 @@ -syntax = "proto3"; - -package memos.store; - -import "google/protobuf/timestamp.proto"; -import "store/instance_setting.proto"; - -option go_package = "gen/store"; - -enum AttachmentStorageType { - ATTACHMENT_STORAGE_TYPE_UNSPECIFIED = 0; - // Attachment is stored locally. AKA, local file system. - LOCAL = 1; - // Attachment is stored in S3. - S3 = 2; - // Attachment is stored in an external storage. The reference is a URL. - EXTERNAL = 3; -} - -message AttachmentPayload { - oneof payload { - S3Object s3_object = 1; - } - - message S3Object { - StorageS3Config s3_config = 1; - // key is the S3 object key. - string key = 2; - // last_presigned_time is the last time the object was presigned. - // This is used to determine if the presigned URL is still valid. - google.protobuf.Timestamp last_presigned_time = 3; - } -} +syntax = "proto3"; + +package memos.store; + +import "google/protobuf/timestamp.proto"; +import "store/instance_setting.proto"; + +option go_package = "gen/store"; + +enum AttachmentStorageType { + ATTACHMENT_STORAGE_TYPE_UNSPECIFIED = 0; + // Attachment is stored locally. AKA, local file system. + LOCAL = 1; + // Attachment is stored in S3. + S3 = 2; + // Attachment is stored in an external storage. The reference is a URL. + EXTERNAL = 3; +} + +message AttachmentPayload { + oneof payload { + S3Object s3_object = 1; + } + + message S3Object { + StorageS3Config s3_config = 1; + // key is the S3 object key. + string key = 2; + // last_presigned_time is the last time the object was presigned. + // This is used to determine if the presigned URL is still valid. + google.protobuf.Timestamp last_presigned_time = 3; + } +} diff --git a/proto/store/idp.proto b/proto/store/idp.proto index eeffb2785..6f69b1dd1 100644 --- a/proto/store/idp.proto +++ b/proto/store/idp.proto @@ -1,42 +1,42 @@ -syntax = "proto3"; - -package memos.store; - -option go_package = "gen/store"; - -message IdentityProvider { - int32 id = 1; - string name = 2; - - enum Type { - TYPE_UNSPECIFIED = 0; - OAUTH2 = 1; - } - Type type = 3; - string identifier_filter = 4; - IdentityProviderConfig config = 5; - string uid = 6; -} - -message IdentityProviderConfig { - oneof config { - OAuth2Config oauth2_config = 1; - } -} - -message FieldMapping { - string identifier = 1; - string display_name = 2; - string email = 3; - string avatar_url = 4; -} - -message OAuth2Config { - string client_id = 1; - string client_secret = 2; - string auth_url = 3; - string token_url = 4; - string user_info_url = 5; - repeated string scopes = 6; - FieldMapping field_mapping = 7; -} +syntax = "proto3"; + +package memos.store; + +option go_package = "gen/store"; + +message IdentityProvider { + int32 id = 1; + string name = 2; + + enum Type { + TYPE_UNSPECIFIED = 0; + OAUTH2 = 1; + } + Type type = 3; + string identifier_filter = 4; + IdentityProviderConfig config = 5; + string uid = 6; +} + +message IdentityProviderConfig { + oneof config { + OAuth2Config oauth2_config = 1; + } +} + +message FieldMapping { + string identifier = 1; + string display_name = 2; + string email = 3; + string avatar_url = 4; +} + +message OAuth2Config { + string client_id = 1; + string client_secret = 2; + string auth_url = 3; + string token_url = 4; + string user_info_url = 5; + repeated string scopes = 6; + FieldMapping field_mapping = 7; +} diff --git a/proto/store/inbox.proto b/proto/store/inbox.proto index e7b400205..545935c21 100644 --- a/proto/store/inbox.proto +++ b/proto/store/inbox.proto @@ -1,24 +1,24 @@ -syntax = "proto3"; - -package memos.store; - -option go_package = "gen/store"; - -message InboxMessage { - message MemoCommentPayload { - int32 memo_id = 1; - int32 related_memo_id = 2; - } - - // The type of the inbox message. - Type type = 1; - oneof payload { - MemoCommentPayload memo_comment = 2; - } - - enum Type { - TYPE_UNSPECIFIED = 0; - // Memo comment notification. - MEMO_COMMENT = 1; - } -} +syntax = "proto3"; + +package memos.store; + +option go_package = "gen/store"; + +message InboxMessage { + message MemoCommentPayload { + int32 memo_id = 1; + int32 related_memo_id = 2; + } + + // The type of the inbox message. + Type type = 1; + oneof payload { + MemoCommentPayload memo_comment = 2; + } + + enum Type { + TYPE_UNSPECIFIED = 0; + // Memo comment notification. + MEMO_COMMENT = 1; + } +} diff --git a/proto/store/instance_setting.proto b/proto/store/instance_setting.proto index 8419e0bce..b06a11585 100644 --- a/proto/store/instance_setting.proto +++ b/proto/store/instance_setting.proto @@ -1,141 +1,141 @@ -syntax = "proto3"; - -package memos.store; - -import "google/type/color.proto"; - -option go_package = "gen/store"; - -enum InstanceSettingKey { - INSTANCE_SETTING_KEY_UNSPECIFIED = 0; - // BASIC is the key for basic settings. - BASIC = 1; - // GENERAL is the key for general settings. - GENERAL = 2; - // STORAGE is the key for storage settings. - STORAGE = 3; - // MEMO_RELATED is the key for memo related settings. - MEMO_RELATED = 4; - // TAGS is the key for tag metadata. - TAGS = 5; - // NOTIFICATION is the key for notification transport settings. - NOTIFICATION = 6; -} - -message InstanceSetting { - InstanceSettingKey key = 1; - oneof value { - InstanceBasicSetting basic_setting = 2; - InstanceGeneralSetting general_setting = 3; - InstanceStorageSetting storage_setting = 4; - InstanceMemoRelatedSetting memo_related_setting = 5; - InstanceTagsSetting tags_setting = 6; - InstanceNotificationSetting notification_setting = 7; - } -} - -message InstanceBasicSetting { - // The secret key for instance. Mainly used for session management. - string secret_key = 1; - // The current schema version of database. - string schema_version = 2; -} - -message InstanceGeneralSetting { - // disallow_user_registration disallows user registration. - bool disallow_user_registration = 2; - // disallow_password_auth disallows password authentication. - bool disallow_password_auth = 3; - // additional_script is the additional script. - string additional_script = 4; - // additional_style is the additional style. - string additional_style = 5; - // custom_profile is the custom profile. - InstanceCustomProfile custom_profile = 6; - // week_start_day_offset is the week start day offset from Sunday. - // 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday - // Default is Sunday. - int32 week_start_day_offset = 7; - // disallow_change_username disallows changing username. - bool disallow_change_username = 8; - // disallow_change_nickname disallows changing nickname. - bool disallow_change_nickname = 9; -} - -message InstanceCustomProfile { - string title = 1; - string description = 2; - string logo_url = 3; -} - -message InstanceStorageSetting { - enum StorageType { - STORAGE_TYPE_UNSPECIFIED = 0; - // STORAGE_TYPE_DATABASE is the database storage type. - DATABASE = 1; - // STORAGE_TYPE_LOCAL is the local storage type. - LOCAL = 2; - // STORAGE_TYPE_S3 is the S3 storage type. - S3 = 3; - } - // storage_type is the storage type. - StorageType storage_type = 1; - // The template of file path. - // e.g. assets/{timestamp}_{filename} - string filepath_template = 2; - // The max upload size in megabytes. - int64 upload_size_limit_mb = 3; - // The S3 config. - StorageS3Config s3_config = 4; -} - -// Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/ -message StorageS3Config { - string access_key_id = 1; - string access_key_secret = 2; - string endpoint = 3; - string region = 4; - string bucket = 5; - bool use_path_style = 6; -} - -message InstanceMemoRelatedSetting { - // display_with_update_time orders and displays memo with update time. - bool display_with_update_time = 2; - // content_length_limit is the limit of content length. Unit is byte. - int32 content_length_limit = 3; - // enable_double_click_edit enables editing on double click. - bool enable_double_click_edit = 4; - // reactions is the list of reactions. - repeated string reactions = 7; -} - -message InstanceTagMetadata { - // Background color for the tag label. - google.type.Color background_color = 1; -} - -message InstanceTagsSetting { - // Map of tag name pattern to tag metadata. - // Each key is treated as an anchored regular expression (^pattern$), - // so a single entry like "project/.*" matches all tags under that prefix. - // Exact tag names are also valid (they are trivially valid regex patterns). - map tags = 1; -} - -message InstanceNotificationSetting { - EmailSetting email = 1; - - message EmailSetting { - bool enabled = 1; - string smtp_host = 2; - int32 smtp_port = 3; - string smtp_username = 4; - string smtp_password = 5; - string from_email = 6; - string from_name = 7; - string reply_to = 8; - bool use_tls = 9; - bool use_ssl = 10; - } -} +syntax = "proto3"; + +package memos.store; + +import "google/type/color.proto"; + +option go_package = "gen/store"; + +enum InstanceSettingKey { + INSTANCE_SETTING_KEY_UNSPECIFIED = 0; + // BASIC is the key for basic settings. + BASIC = 1; + // GENERAL is the key for general settings. + GENERAL = 2; + // STORAGE is the key for storage settings. + STORAGE = 3; + // MEMO_RELATED is the key for memo related settings. + MEMO_RELATED = 4; + // TAGS is the key for tag metadata. + TAGS = 5; + // NOTIFICATION is the key for notification transport settings. + NOTIFICATION = 6; +} + +message InstanceSetting { + InstanceSettingKey key = 1; + oneof value { + InstanceBasicSetting basic_setting = 2; + InstanceGeneralSetting general_setting = 3; + InstanceStorageSetting storage_setting = 4; + InstanceMemoRelatedSetting memo_related_setting = 5; + InstanceTagsSetting tags_setting = 6; + InstanceNotificationSetting notification_setting = 7; + } +} + +message InstanceBasicSetting { + // The secret key for instance. Mainly used for session management. + string secret_key = 1; + // The current schema version of database. + string schema_version = 2; +} + +message InstanceGeneralSetting { + // disallow_user_registration disallows user registration. + bool disallow_user_registration = 2; + // disallow_password_auth disallows password authentication. + bool disallow_password_auth = 3; + // additional_script is the additional script. + string additional_script = 4; + // additional_style is the additional style. + string additional_style = 5; + // custom_profile is the custom profile. + InstanceCustomProfile custom_profile = 6; + // week_start_day_offset is the week start day offset from Sunday. + // 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday + // Default is Sunday. + int32 week_start_day_offset = 7; + // disallow_change_username disallows changing username. + bool disallow_change_username = 8; + // disallow_change_nickname disallows changing nickname. + bool disallow_change_nickname = 9; +} + +message InstanceCustomProfile { + string title = 1; + string description = 2; + string logo_url = 3; +} + +message InstanceStorageSetting { + enum StorageType { + STORAGE_TYPE_UNSPECIFIED = 0; + // STORAGE_TYPE_DATABASE is the database storage type. + DATABASE = 1; + // STORAGE_TYPE_LOCAL is the local storage type. + LOCAL = 2; + // STORAGE_TYPE_S3 is the S3 storage type. + S3 = 3; + } + // storage_type is the storage type. + StorageType storage_type = 1; + // The template of file path. + // e.g. assets/{timestamp}_{filename} + string filepath_template = 2; + // The max upload size in megabytes. + int64 upload_size_limit_mb = 3; + // The S3 config. + StorageS3Config s3_config = 4; +} + +// Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/ +message StorageS3Config { + string access_key_id = 1; + string access_key_secret = 2; + string endpoint = 3; + string region = 4; + string bucket = 5; + bool use_path_style = 6; +} + +message InstanceMemoRelatedSetting { + // display_with_update_time orders and displays memo with update time. + bool display_with_update_time = 2; + // content_length_limit is the limit of content length. Unit is byte. + int32 content_length_limit = 3; + // enable_double_click_edit enables editing on double click. + bool enable_double_click_edit = 4; + // reactions is the list of reactions. + repeated string reactions = 7; +} + +message InstanceTagMetadata { + // Background color for the tag label. + google.type.Color background_color = 1; +} + +message InstanceTagsSetting { + // Map of tag name pattern to tag metadata. + // Each key is treated as an anchored regular expression (^pattern$), + // so a single entry like "project/.*" matches all tags under that prefix. + // Exact tag names are also valid (they are trivially valid regex patterns). + map tags = 1; +} + +message InstanceNotificationSetting { + EmailSetting email = 1; + + message EmailSetting { + bool enabled = 1; + string smtp_host = 2; + int32 smtp_port = 3; + string smtp_username = 4; + string smtp_password = 5; + string from_email = 6; + string from_name = 7; + string reply_to = 8; + bool use_tls = 9; + bool use_ssl = 10; + } +} diff --git a/proto/store/memo.proto b/proto/store/memo.proto index 35e6b1fb2..6e0eb7c86 100644 --- a/proto/store/memo.proto +++ b/proto/store/memo.proto @@ -1,29 +1,29 @@ -syntax = "proto3"; - -package memos.store; - -option go_package = "gen/store"; - -message MemoPayload { - Property property = 1; - - Location location = 2; - - repeated string tags = 3; - - // The calculated properties from the memo content. - message Property { - bool has_link = 1; - bool has_task_list = 2; - bool has_code = 3; - bool has_incomplete_tasks = 4; - // The title extracted from the first H1 heading, if present. - string title = 5; - } - - message Location { - string placeholder = 1; - double latitude = 2; - double longitude = 3; - } -} +syntax = "proto3"; + +package memos.store; + +option go_package = "gen/store"; + +message MemoPayload { + Property property = 1; + + Location location = 2; + + repeated string tags = 3; + + // The calculated properties from the memo content. + message Property { + bool has_link = 1; + bool has_task_list = 2; + bool has_code = 3; + bool has_incomplete_tasks = 4; + // The title extracted from the first H1 heading, if present. + string title = 5; + } + + message Location { + string placeholder = 1; + double latitude = 2; + double longitude = 3; + } +} diff --git a/proto/store/user_setting.proto b/proto/store/user_setting.proto index ee31d878a..6a065e609 100644 --- a/proto/store/user_setting.proto +++ b/proto/store/user_setting.proto @@ -1,113 +1,113 @@ -syntax = "proto3"; - -package memos.store; - -import "google/protobuf/timestamp.proto"; - -option go_package = "gen/store"; - -message UserSetting { - enum Key { - KEY_UNSPECIFIED = 0; - // General user settings. - GENERAL = 1; - // The shortcuts of the user. - SHORTCUTS = 4; - // The webhooks of the user. - WEBHOOKS = 5; - // Refresh tokens for the user. - REFRESH_TOKENS = 6; - // Personal access tokens for the user. - PERSONAL_ACCESS_TOKENS = 7; - } - - int32 user_id = 1; - - Key key = 2; - oneof value { - GeneralUserSetting general = 3; - ShortcutsUserSetting shortcuts = 6; - WebhooksUserSetting webhooks = 7; - RefreshTokensUserSetting refresh_tokens = 8; - PersonalAccessTokensUserSetting personal_access_tokens = 9; - } -} - -message GeneralUserSetting { - // The user's locale. - string locale = 1; - // The user's memo visibility setting. - string memo_visibility = 2; - // The user's theme preference. - // This references a CSS file in the web/public/themes/ directory. - string theme = 3; -} - -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 { - // 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; - // Optional. Operating system (e.g., "iOS 17.0", "Windows 11"). - string os = 4; - // Optional. Browser name and version (e.g., "Chrome 119.0"). - string browser = 5; - } - - repeated RefreshToken refresh_tokens = 1; -} - -message PersonalAccessTokensUserSetting { - message PersonalAccessToken { - // Unique identifier for this token - string token_id = 1; - // SHA-256 hash of the actual token - string token_hash = 2; - // User-provided description - string description = 3; - // When the token expires (null = never) - google.protobuf.Timestamp expires_at = 4; - // When the token was created - google.protobuf.Timestamp created_at = 5; - // When the token was last used - google.protobuf.Timestamp last_used_at = 6; - } - repeated PersonalAccessToken tokens = 1; -} - -message ShortcutsUserSetting { - message Shortcut { - string id = 1; - string title = 2; - string filter = 3; - } - repeated Shortcut shortcuts = 1; -} - -message WebhooksUserSetting { - message Webhook { - // Unique identifier for the webhook - string id = 1; - // Descriptive title for the webhook - string title = 2; - // The webhook URL endpoint - string url = 3; - } - repeated Webhook webhooks = 1; -} +syntax = "proto3"; + +package memos.store; + +import "google/protobuf/timestamp.proto"; + +option go_package = "gen/store"; + +message UserSetting { + enum Key { + KEY_UNSPECIFIED = 0; + // General user settings. + GENERAL = 1; + // The shortcuts of the user. + SHORTCUTS = 4; + // The webhooks of the user. + WEBHOOKS = 5; + // Refresh tokens for the user. + REFRESH_TOKENS = 6; + // Personal access tokens for the user. + PERSONAL_ACCESS_TOKENS = 7; + } + + int32 user_id = 1; + + Key key = 2; + oneof value { + GeneralUserSetting general = 3; + ShortcutsUserSetting shortcuts = 6; + WebhooksUserSetting webhooks = 7; + RefreshTokensUserSetting refresh_tokens = 8; + PersonalAccessTokensUserSetting personal_access_tokens = 9; + } +} + +message GeneralUserSetting { + // The user's locale. + string locale = 1; + // The user's memo visibility setting. + string memo_visibility = 2; + // The user's theme preference. + // This references a CSS file in the web/public/themes/ directory. + string theme = 3; +} + +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 { + // 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; + // Optional. Operating system (e.g., "iOS 17.0", "Windows 11"). + string os = 4; + // Optional. Browser name and version (e.g., "Chrome 119.0"). + string browser = 5; + } + + repeated RefreshToken refresh_tokens = 1; +} + +message PersonalAccessTokensUserSetting { + message PersonalAccessToken { + // Unique identifier for this token + string token_id = 1; + // SHA-256 hash of the actual token + string token_hash = 2; + // User-provided description + string description = 3; + // When the token expires (null = never) + google.protobuf.Timestamp expires_at = 4; + // When the token was created + google.protobuf.Timestamp created_at = 5; + // When the token was last used + google.protobuf.Timestamp last_used_at = 6; + } + repeated PersonalAccessToken tokens = 1; +} + +message ShortcutsUserSetting { + message Shortcut { + string id = 1; + string title = 2; + string filter = 3; + } + repeated Shortcut shortcuts = 1; +} + +message WebhooksUserSetting { + message Webhook { + // Unique identifier for the webhook + string id = 1; + // Descriptive title for the webhook + string title = 2; + // The webhook URL endpoint + string url = 3; + } + repeated Webhook webhooks = 1; +}