chore(webhook): reveal-later signing secret flow
Generate webhook signing secrets server-side and let users reveal them on demand, replacing the create-dialog secret controls that surfaced internal mask state (Status / Generate & Copy / Clear / Pending) to users. - Add owner-gated GetUserWebhookSigningSecret RPC — the only path that returns the secret; list/create/update responses still omit it. - Generate the secret server-side on create (webhook.GenerateSigningSecret), so validity no longer depends on the client. - Rename UserWebhook.has_signing_secret -> signing_secret_set for parity with the existing api_key_set field. - Create dialog drops the secret section to a one-line note; the generated secret is shown once right after create and revealable from Edit later.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
@@ -104,6 +105,17 @@ func resolveSigningKey(secret string) ([]byte, error) {
|
||||
return []byte(secret), nil
|
||||
}
|
||||
|
||||
// GenerateSigningSecret returns a new Standard Webhooks signing secret in the
|
||||
// "whsec_<base64>" form, backed by 32 cryptographically-random bytes — comfortably
|
||||
// within the spec's 24–64 byte range.
|
||||
func GenerateSigningSecret() (string, error) {
|
||||
buf := make([]byte, 32)
|
||||
if _, err := rand.Read(buf); err != nil {
|
||||
return "", errors.Wrap(err, "failed to read random bytes for signing secret")
|
||||
}
|
||||
return "whsec_" + base64.StdEncoding.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
// Post posts the message to webhook endpoint.
|
||||
func Post(requestPayload *WebhookRequestPayload) error {
|
||||
body, err := json.Marshal(requestPayload)
|
||||
|
||||
@@ -41,6 +41,21 @@ func TestResolveSigningKey(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGenerateSigningSecret(t *testing.T) {
|
||||
secret, err := GenerateSigningSecret()
|
||||
require.NoError(t, err)
|
||||
require.True(t, strings.HasPrefix(secret, "whsec_"), "generated secret must use the whsec_ prefix")
|
||||
require.NoError(t, ValidateSigningSecret(secret), "generated secret must pass validation")
|
||||
|
||||
key, err := resolveSigningKey(secret)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, key, 32, "generated secret must decode to 32 raw bytes")
|
||||
|
||||
other, err := GenerateSigningSecret()
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, secret, other, "each generated secret must be unique")
|
||||
}
|
||||
|
||||
func TestValidateSigningSecret(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -170,6 +170,14 @@ service UserService {
|
||||
option (google.api.method_signature) = "name";
|
||||
}
|
||||
|
||||
// GetUserWebhookSigningSecret returns the signing secret for a webhook.
|
||||
// The secret is returned only through this explicit, owner-gated call; it is
|
||||
// never included in List/Create/Update responses.
|
||||
rpc GetUserWebhookSigningSecret(GetUserWebhookSigningSecretRequest) returns (GetUserWebhookSigningSecretResponse) {
|
||||
option (google.api.http) = {get: "/api/v1/{name=users/*/webhooks/*}:getSigningSecret"};
|
||||
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"};
|
||||
@@ -715,8 +723,8 @@ message UserWebhook {
|
||||
// This field is input-only; it is never returned in responses.
|
||||
string signing_secret = 6 [(google.api.field_behavior) = INPUT_ONLY];
|
||||
|
||||
// Whether this webhook has a signing secret configured.
|
||||
bool has_signing_secret = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
|
||||
// Whether a signing secret is configured for this webhook.
|
||||
bool signing_secret_set = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
|
||||
}
|
||||
|
||||
message ListUserWebhooksRequest {
|
||||
@@ -753,6 +761,17 @@ message DeleteUserWebhookRequest {
|
||||
string name = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
||||
message GetUserWebhookSigningSecretRequest {
|
||||
// The name of the webhook whose signing secret to reveal.
|
||||
// Format: users/{user}/webhooks/{webhook}
|
||||
string name = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
||||
message GetUserWebhookSigningSecretResponse {
|
||||
// The signing secret, in the Standard Webhooks "whsec_<base64>" form.
|
||||
string signing_secret = 1;
|
||||
}
|
||||
|
||||
message UserNotification {
|
||||
option (google.api.resource) = {
|
||||
type: "memos.api.v1/UserNotification"
|
||||
|
||||
@@ -95,6 +95,9 @@ const (
|
||||
// UserServiceDeleteUserWebhookProcedure is the fully-qualified name of the UserService's
|
||||
// DeleteUserWebhook RPC.
|
||||
UserServiceDeleteUserWebhookProcedure = "/memos.api.v1.UserService/DeleteUserWebhook"
|
||||
// UserServiceGetUserWebhookSigningSecretProcedure is the fully-qualified name of the UserService's
|
||||
// GetUserWebhookSigningSecret RPC.
|
||||
UserServiceGetUserWebhookSigningSecretProcedure = "/memos.api.v1.UserService/GetUserWebhookSigningSecret"
|
||||
// UserServiceListUserNotificationsProcedure is the fully-qualified name of the UserService's
|
||||
// ListUserNotifications RPC.
|
||||
UserServiceListUserNotificationsProcedure = "/memos.api.v1.UserService/ListUserNotifications"
|
||||
@@ -155,6 +158,10 @@ type UserServiceClient interface {
|
||||
UpdateUserWebhook(context.Context, *connect.Request[v1.UpdateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error)
|
||||
// DeleteUserWebhook deletes a webhook for a user.
|
||||
DeleteUserWebhook(context.Context, *connect.Request[v1.DeleteUserWebhookRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// GetUserWebhookSigningSecret returns the signing secret for a webhook.
|
||||
// The secret is returned only through this explicit, owner-gated call; it is
|
||||
// never included in List/Create/Update responses.
|
||||
GetUserWebhookSigningSecret(context.Context, *connect.Request[v1.GetUserWebhookSigningSecretRequest]) (*connect.Response[v1.GetUserWebhookSigningSecretResponse], error)
|
||||
// ListUserNotifications lists notifications for a user.
|
||||
ListUserNotifications(context.Context, *connect.Request[v1.ListUserNotificationsRequest]) (*connect.Response[v1.ListUserNotificationsResponse], error)
|
||||
// UpdateUserNotification updates a notification.
|
||||
@@ -306,6 +313,12 @@ func NewUserServiceClient(httpClient connect.HTTPClient, baseURL string, opts ..
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUserWebhook")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getUserWebhookSigningSecret: connect.NewClient[v1.GetUserWebhookSigningSecretRequest, v1.GetUserWebhookSigningSecretResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceGetUserWebhookSigningSecretProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("GetUserWebhookSigningSecret")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listUserNotifications: connect.NewClient[v1.ListUserNotificationsRequest, v1.ListUserNotificationsResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceListUserNotificationsProcedure,
|
||||
@@ -329,31 +342,32 @@ func NewUserServiceClient(httpClient connect.HTTPClient, baseURL string, opts ..
|
||||
|
||||
// userServiceClient implements UserServiceClient.
|
||||
type userServiceClient struct {
|
||||
listUsers *connect.Client[v1.ListUsersRequest, v1.ListUsersResponse]
|
||||
batchGetUsers *connect.Client[v1.BatchGetUsersRequest, v1.BatchGetUsersResponse]
|
||||
getUser *connect.Client[v1.GetUserRequest, v1.User]
|
||||
createUser *connect.Client[v1.CreateUserRequest, v1.User]
|
||||
updateUser *connect.Client[v1.UpdateUserRequest, v1.User]
|
||||
deleteUser *connect.Client[v1.DeleteUserRequest, emptypb.Empty]
|
||||
listAllUserStats *connect.Client[v1.ListAllUserStatsRequest, v1.ListAllUserStatsResponse]
|
||||
getUserStats *connect.Client[v1.GetUserStatsRequest, v1.UserStats]
|
||||
getUserSetting *connect.Client[v1.GetUserSettingRequest, v1.UserSetting]
|
||||
updateUserSetting *connect.Client[v1.UpdateUserSettingRequest, v1.UserSetting]
|
||||
listUserSettings *connect.Client[v1.ListUserSettingsRequest, v1.ListUserSettingsResponse]
|
||||
listLinkedIdentities *connect.Client[v1.ListLinkedIdentitiesRequest, v1.ListLinkedIdentitiesResponse]
|
||||
createLinkedIdentity *connect.Client[v1.CreateLinkedIdentityRequest, v1.LinkedIdentity]
|
||||
getLinkedIdentity *connect.Client[v1.GetLinkedIdentityRequest, v1.LinkedIdentity]
|
||||
deleteLinkedIdentity *connect.Client[v1.DeleteLinkedIdentityRequest, emptypb.Empty]
|
||||
listPersonalAccessTokens *connect.Client[v1.ListPersonalAccessTokensRequest, v1.ListPersonalAccessTokensResponse]
|
||||
createPersonalAccessToken *connect.Client[v1.CreatePersonalAccessTokenRequest, v1.CreatePersonalAccessTokenResponse]
|
||||
deletePersonalAccessToken *connect.Client[v1.DeletePersonalAccessTokenRequest, emptypb.Empty]
|
||||
listUserWebhooks *connect.Client[v1.ListUserWebhooksRequest, v1.ListUserWebhooksResponse]
|
||||
createUserWebhook *connect.Client[v1.CreateUserWebhookRequest, v1.UserWebhook]
|
||||
updateUserWebhook *connect.Client[v1.UpdateUserWebhookRequest, v1.UserWebhook]
|
||||
deleteUserWebhook *connect.Client[v1.DeleteUserWebhookRequest, emptypb.Empty]
|
||||
listUserNotifications *connect.Client[v1.ListUserNotificationsRequest, v1.ListUserNotificationsResponse]
|
||||
updateUserNotification *connect.Client[v1.UpdateUserNotificationRequest, v1.UserNotification]
|
||||
deleteUserNotification *connect.Client[v1.DeleteUserNotificationRequest, emptypb.Empty]
|
||||
listUsers *connect.Client[v1.ListUsersRequest, v1.ListUsersResponse]
|
||||
batchGetUsers *connect.Client[v1.BatchGetUsersRequest, v1.BatchGetUsersResponse]
|
||||
getUser *connect.Client[v1.GetUserRequest, v1.User]
|
||||
createUser *connect.Client[v1.CreateUserRequest, v1.User]
|
||||
updateUser *connect.Client[v1.UpdateUserRequest, v1.User]
|
||||
deleteUser *connect.Client[v1.DeleteUserRequest, emptypb.Empty]
|
||||
listAllUserStats *connect.Client[v1.ListAllUserStatsRequest, v1.ListAllUserStatsResponse]
|
||||
getUserStats *connect.Client[v1.GetUserStatsRequest, v1.UserStats]
|
||||
getUserSetting *connect.Client[v1.GetUserSettingRequest, v1.UserSetting]
|
||||
updateUserSetting *connect.Client[v1.UpdateUserSettingRequest, v1.UserSetting]
|
||||
listUserSettings *connect.Client[v1.ListUserSettingsRequest, v1.ListUserSettingsResponse]
|
||||
listLinkedIdentities *connect.Client[v1.ListLinkedIdentitiesRequest, v1.ListLinkedIdentitiesResponse]
|
||||
createLinkedIdentity *connect.Client[v1.CreateLinkedIdentityRequest, v1.LinkedIdentity]
|
||||
getLinkedIdentity *connect.Client[v1.GetLinkedIdentityRequest, v1.LinkedIdentity]
|
||||
deleteLinkedIdentity *connect.Client[v1.DeleteLinkedIdentityRequest, emptypb.Empty]
|
||||
listPersonalAccessTokens *connect.Client[v1.ListPersonalAccessTokensRequest, v1.ListPersonalAccessTokensResponse]
|
||||
createPersonalAccessToken *connect.Client[v1.CreatePersonalAccessTokenRequest, v1.CreatePersonalAccessTokenResponse]
|
||||
deletePersonalAccessToken *connect.Client[v1.DeletePersonalAccessTokenRequest, emptypb.Empty]
|
||||
listUserWebhooks *connect.Client[v1.ListUserWebhooksRequest, v1.ListUserWebhooksResponse]
|
||||
createUserWebhook *connect.Client[v1.CreateUserWebhookRequest, v1.UserWebhook]
|
||||
updateUserWebhook *connect.Client[v1.UpdateUserWebhookRequest, v1.UserWebhook]
|
||||
deleteUserWebhook *connect.Client[v1.DeleteUserWebhookRequest, emptypb.Empty]
|
||||
getUserWebhookSigningSecret *connect.Client[v1.GetUserWebhookSigningSecretRequest, v1.GetUserWebhookSigningSecretResponse]
|
||||
listUserNotifications *connect.Client[v1.ListUserNotificationsRequest, v1.ListUserNotificationsResponse]
|
||||
updateUserNotification *connect.Client[v1.UpdateUserNotificationRequest, v1.UserNotification]
|
||||
deleteUserNotification *connect.Client[v1.DeleteUserNotificationRequest, emptypb.Empty]
|
||||
}
|
||||
|
||||
// ListUsers calls memos.api.v1.UserService.ListUsers.
|
||||
@@ -466,6 +480,11 @@ func (c *userServiceClient) DeleteUserWebhook(ctx context.Context, req *connect.
|
||||
return c.deleteUserWebhook.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetUserWebhookSigningSecret calls memos.api.v1.UserService.GetUserWebhookSigningSecret.
|
||||
func (c *userServiceClient) GetUserWebhookSigningSecret(ctx context.Context, req *connect.Request[v1.GetUserWebhookSigningSecretRequest]) (*connect.Response[v1.GetUserWebhookSigningSecretResponse], error) {
|
||||
return c.getUserWebhookSigningSecret.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListUserNotifications calls memos.api.v1.UserService.ListUserNotifications.
|
||||
func (c *userServiceClient) ListUserNotifications(ctx context.Context, req *connect.Request[v1.ListUserNotificationsRequest]) (*connect.Response[v1.ListUserNotificationsResponse], error) {
|
||||
return c.listUserNotifications.CallUnary(ctx, req)
|
||||
@@ -530,6 +549,10 @@ type UserServiceHandler interface {
|
||||
UpdateUserWebhook(context.Context, *connect.Request[v1.UpdateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error)
|
||||
// DeleteUserWebhook deletes a webhook for a user.
|
||||
DeleteUserWebhook(context.Context, *connect.Request[v1.DeleteUserWebhookRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// GetUserWebhookSigningSecret returns the signing secret for a webhook.
|
||||
// The secret is returned only through this explicit, owner-gated call; it is
|
||||
// never included in List/Create/Update responses.
|
||||
GetUserWebhookSigningSecret(context.Context, *connect.Request[v1.GetUserWebhookSigningSecretRequest]) (*connect.Response[v1.GetUserWebhookSigningSecretResponse], error)
|
||||
// ListUserNotifications lists notifications for a user.
|
||||
ListUserNotifications(context.Context, *connect.Request[v1.ListUserNotificationsRequest]) (*connect.Response[v1.ListUserNotificationsResponse], error)
|
||||
// UpdateUserNotification updates a notification.
|
||||
@@ -677,6 +700,12 @@ func NewUserServiceHandler(svc UserServiceHandler, opts ...connect.HandlerOption
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUserWebhook")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceGetUserWebhookSigningSecretHandler := connect.NewUnaryHandler(
|
||||
UserServiceGetUserWebhookSigningSecretProcedure,
|
||||
svc.GetUserWebhookSigningSecret,
|
||||
connect.WithSchema(userServiceMethods.ByName("GetUserWebhookSigningSecret")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceListUserNotificationsHandler := connect.NewUnaryHandler(
|
||||
UserServiceListUserNotificationsProcedure,
|
||||
svc.ListUserNotifications,
|
||||
@@ -741,6 +770,8 @@ func NewUserServiceHandler(svc UserServiceHandler, opts ...connect.HandlerOption
|
||||
userServiceUpdateUserWebhookHandler.ServeHTTP(w, r)
|
||||
case UserServiceDeleteUserWebhookProcedure:
|
||||
userServiceDeleteUserWebhookHandler.ServeHTTP(w, r)
|
||||
case UserServiceGetUserWebhookSigningSecretProcedure:
|
||||
userServiceGetUserWebhookSigningSecretHandler.ServeHTTP(w, r)
|
||||
case UserServiceListUserNotificationsProcedure:
|
||||
userServiceListUserNotificationsHandler.ServeHTTP(w, r)
|
||||
case UserServiceUpdateUserNotificationProcedure:
|
||||
@@ -844,6 +875,10 @@ func (UnimplementedUserServiceHandler) DeleteUserWebhook(context.Context, *conne
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.DeleteUserWebhook is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) GetUserWebhookSigningSecret(context.Context, *connect.Request[v1.GetUserWebhookSigningSecretRequest]) (*connect.Response[v1.GetUserWebhookSigningSecretResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.GetUserWebhookSigningSecret is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) ListUserNotifications(context.Context, *connect.Request[v1.ListUserNotificationsRequest]) (*connect.Response[v1.ListUserNotificationsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListUserNotifications is not implemented"))
|
||||
}
|
||||
|
||||
+228
-128
@@ -180,7 +180,7 @@ func (x UserNotification_Status) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use UserNotification_Status.Descriptor instead.
|
||||
func (UserNotification_Status) EnumDescriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{36, 0}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{38, 0}
|
||||
}
|
||||
|
||||
type UserNotification_Type int32
|
||||
@@ -229,7 +229,7 @@ func (x UserNotification_Type) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use UserNotification_Type.Descriptor instead.
|
||||
func (UserNotification_Type) EnumDescriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{36, 1}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{38, 1}
|
||||
}
|
||||
|
||||
type User struct {
|
||||
@@ -2166,8 +2166,8 @@ type UserWebhook struct {
|
||||
// Optional. Signing secret used to HMAC-SHA256 sign the webhook request body.
|
||||
// This field is input-only; it is never returned in responses.
|
||||
SigningSecret string `protobuf:"bytes,6,opt,name=signing_secret,json=signingSecret,proto3" json:"signing_secret,omitempty"`
|
||||
// Whether this webhook has a signing secret configured.
|
||||
HasSigningSecret bool `protobuf:"varint,7,opt,name=has_signing_secret,json=hasSigningSecret,proto3" json:"has_signing_secret,omitempty"`
|
||||
// Whether a signing secret is configured for this webhook.
|
||||
SigningSecretSet bool `protobuf:"varint,7,opt,name=signing_secret_set,json=signingSecretSet,proto3" json:"signing_secret_set,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -2244,9 +2244,9 @@ func (x *UserWebhook) GetSigningSecret() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *UserWebhook) GetHasSigningSecret() bool {
|
||||
func (x *UserWebhook) GetSigningSecretSet() bool {
|
||||
if x != nil {
|
||||
return x.HasSigningSecret
|
||||
return x.SigningSecretSet
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -2497,6 +2497,97 @@ func (x *DeleteUserWebhookRequest) GetName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetUserWebhookSigningSecretRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The name of the webhook whose signing secret to reveal.
|
||||
// Format: users/{user}/webhooks/{webhook}
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetUserWebhookSigningSecretRequest) Reset() {
|
||||
*x = GetUserWebhookSigningSecretRequest{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[36]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetUserWebhookSigningSecretRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetUserWebhookSigningSecretRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetUserWebhookSigningSecretRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[36]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetUserWebhookSigningSecretRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetUserWebhookSigningSecretRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{36}
|
||||
}
|
||||
|
||||
func (x *GetUserWebhookSigningSecretRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetUserWebhookSigningSecretResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The signing secret, in the Standard Webhooks "whsec_<base64>" form.
|
||||
SigningSecret string `protobuf:"bytes,1,opt,name=signing_secret,json=signingSecret,proto3" json:"signing_secret,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetUserWebhookSigningSecretResponse) Reset() {
|
||||
*x = GetUserWebhookSigningSecretResponse{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[37]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetUserWebhookSigningSecretResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetUserWebhookSigningSecretResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetUserWebhookSigningSecretResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[37]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetUserWebhookSigningSecretResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetUserWebhookSigningSecretResponse) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{37}
|
||||
}
|
||||
|
||||
func (x *GetUserWebhookSigningSecretResponse) GetSigningSecret() string {
|
||||
if x != nil {
|
||||
return x.SigningSecret
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type UserNotification struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The resource name of the notification.
|
||||
@@ -2524,7 +2615,7 @@ type UserNotification struct {
|
||||
|
||||
func (x *UserNotification) Reset() {
|
||||
*x = UserNotification{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[36]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[38]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2536,7 +2627,7 @@ func (x *UserNotification) String() string {
|
||||
func (*UserNotification) ProtoMessage() {}
|
||||
|
||||
func (x *UserNotification) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[36]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[38]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2549,7 +2640,7 @@ func (x *UserNotification) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use UserNotification.ProtoReflect.Descriptor instead.
|
||||
func (*UserNotification) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{36}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{38}
|
||||
}
|
||||
|
||||
func (x *UserNotification) GetName() string {
|
||||
@@ -2649,7 +2740,7 @@ type ListUserNotificationsRequest struct {
|
||||
|
||||
func (x *ListUserNotificationsRequest) Reset() {
|
||||
*x = ListUserNotificationsRequest{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[37]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[39]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2661,7 +2752,7 @@ func (x *ListUserNotificationsRequest) String() string {
|
||||
func (*ListUserNotificationsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListUserNotificationsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[37]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[39]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2674,7 +2765,7 @@ func (x *ListUserNotificationsRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ListUserNotificationsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListUserNotificationsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{37}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{39}
|
||||
}
|
||||
|
||||
func (x *ListUserNotificationsRequest) GetParent() string {
|
||||
@@ -2715,7 +2806,7 @@ type ListUserNotificationsResponse struct {
|
||||
|
||||
func (x *ListUserNotificationsResponse) Reset() {
|
||||
*x = ListUserNotificationsResponse{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[38]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[40]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2727,7 +2818,7 @@ func (x *ListUserNotificationsResponse) String() string {
|
||||
func (*ListUserNotificationsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListUserNotificationsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[38]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[40]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2740,7 +2831,7 @@ func (x *ListUserNotificationsResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ListUserNotificationsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListUserNotificationsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{38}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{40}
|
||||
}
|
||||
|
||||
func (x *ListUserNotificationsResponse) GetNotifications() []*UserNotification {
|
||||
@@ -2767,7 +2858,7 @@ type UpdateUserNotificationRequest struct {
|
||||
|
||||
func (x *UpdateUserNotificationRequest) Reset() {
|
||||
*x = UpdateUserNotificationRequest{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[39]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[41]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2779,7 +2870,7 @@ func (x *UpdateUserNotificationRequest) String() string {
|
||||
func (*UpdateUserNotificationRequest) ProtoMessage() {}
|
||||
|
||||
func (x *UpdateUserNotificationRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[39]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[41]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2792,7 +2883,7 @@ func (x *UpdateUserNotificationRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use UpdateUserNotificationRequest.ProtoReflect.Descriptor instead.
|
||||
func (*UpdateUserNotificationRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{39}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{41}
|
||||
}
|
||||
|
||||
func (x *UpdateUserNotificationRequest) GetNotification() *UserNotification {
|
||||
@@ -2819,7 +2910,7 @@ type DeleteUserNotificationRequest struct {
|
||||
|
||||
func (x *DeleteUserNotificationRequest) Reset() {
|
||||
*x = DeleteUserNotificationRequest{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[40]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[42]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2831,7 +2922,7 @@ func (x *DeleteUserNotificationRequest) String() string {
|
||||
func (*DeleteUserNotificationRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteUserNotificationRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[40]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[42]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2844,7 +2935,7 @@ func (x *DeleteUserNotificationRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use DeleteUserNotificationRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteUserNotificationRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{40}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{42}
|
||||
}
|
||||
|
||||
func (x *DeleteUserNotificationRequest) GetName() string {
|
||||
@@ -2867,7 +2958,7 @@ type UserStats_MemoTypeStats struct {
|
||||
|
||||
func (x *UserStats_MemoTypeStats) Reset() {
|
||||
*x = UserStats_MemoTypeStats{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[42]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[43]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2879,7 +2970,7 @@ func (x *UserStats_MemoTypeStats) String() string {
|
||||
func (*UserStats_MemoTypeStats) ProtoMessage() {}
|
||||
|
||||
func (x *UserStats_MemoTypeStats) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[42]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[43]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2892,7 +2983,7 @@ func (x *UserStats_MemoTypeStats) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use UserStats_MemoTypeStats.ProtoReflect.Descriptor instead.
|
||||
func (*UserStats_MemoTypeStats) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{9, 1}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{9, 0}
|
||||
}
|
||||
|
||||
func (x *UserStats_MemoTypeStats) GetLinkCount() int32 {
|
||||
@@ -2940,7 +3031,7 @@ type UserSetting_GeneralSetting struct {
|
||||
|
||||
func (x *UserSetting_GeneralSetting) Reset() {
|
||||
*x = UserSetting_GeneralSetting{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[43]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[45]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2952,7 +3043,7 @@ func (x *UserSetting_GeneralSetting) String() string {
|
||||
func (*UserSetting_GeneralSetting) ProtoMessage() {}
|
||||
|
||||
func (x *UserSetting_GeneralSetting) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[43]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[45]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -3003,7 +3094,7 @@ type UserSetting_TagMetadata struct {
|
||||
|
||||
func (x *UserSetting_TagMetadata) Reset() {
|
||||
*x = UserSetting_TagMetadata{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[44]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[46]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -3015,7 +3106,7 @@ func (x *UserSetting_TagMetadata) String() string {
|
||||
func (*UserSetting_TagMetadata) ProtoMessage() {}
|
||||
|
||||
func (x *UserSetting_TagMetadata) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[44]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[46]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -3057,7 +3148,7 @@ type UserSetting_TagsSetting struct {
|
||||
|
||||
func (x *UserSetting_TagsSetting) Reset() {
|
||||
*x = UserSetting_TagsSetting{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[45]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[47]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -3069,7 +3160,7 @@ func (x *UserSetting_TagsSetting) String() string {
|
||||
func (*UserSetting_TagsSetting) ProtoMessage() {}
|
||||
|
||||
func (x *UserSetting_TagsSetting) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[45]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[47]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -3103,7 +3194,7 @@ type UserSetting_WebhooksSetting struct {
|
||||
|
||||
func (x *UserSetting_WebhooksSetting) Reset() {
|
||||
*x = UserSetting_WebhooksSetting{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[46]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[48]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -3115,7 +3206,7 @@ func (x *UserSetting_WebhooksSetting) String() string {
|
||||
func (*UserSetting_WebhooksSetting) ProtoMessage() {}
|
||||
|
||||
func (x *UserSetting_WebhooksSetting) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[46]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[48]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -3156,7 +3247,7 @@ type UserNotification_MemoCommentPayload struct {
|
||||
|
||||
func (x *UserNotification_MemoCommentPayload) Reset() {
|
||||
*x = UserNotification_MemoCommentPayload{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[48]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[50]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -3168,7 +3259,7 @@ func (x *UserNotification_MemoCommentPayload) String() string {
|
||||
func (*UserNotification_MemoCommentPayload) ProtoMessage() {}
|
||||
|
||||
func (x *UserNotification_MemoCommentPayload) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[48]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[50]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -3181,7 +3272,7 @@ func (x *UserNotification_MemoCommentPayload) ProtoReflect() protoreflect.Messag
|
||||
|
||||
// Deprecated: Use UserNotification_MemoCommentPayload.ProtoReflect.Descriptor instead.
|
||||
func (*UserNotification_MemoCommentPayload) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{36, 0}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{38, 0}
|
||||
}
|
||||
|
||||
func (x *UserNotification_MemoCommentPayload) GetMemo() string {
|
||||
@@ -3230,7 +3321,7 @@ type UserNotification_MemoMentionPayload struct {
|
||||
|
||||
func (x *UserNotification_MemoMentionPayload) Reset() {
|
||||
*x = UserNotification_MemoMentionPayload{}
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[49]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[51]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -3242,7 +3333,7 @@ func (x *UserNotification_MemoMentionPayload) String() string {
|
||||
func (*UserNotification_MemoMentionPayload) ProtoMessage() {}
|
||||
|
||||
func (x *UserNotification_MemoMentionPayload) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[49]
|
||||
mi := &file_api_v1_user_service_proto_msgTypes[51]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -3255,7 +3346,7 @@ func (x *UserNotification_MemoMentionPayload) ProtoReflect() protoreflect.Messag
|
||||
|
||||
// Deprecated: Use UserNotification_MemoMentionPayload.ProtoReflect.Descriptor instead.
|
||||
func (*UserNotification_MemoMentionPayload) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{36, 1}
|
||||
return file_api_v1_user_service_proto_rawDescGZIP(), []int{38, 1}
|
||||
}
|
||||
|
||||
func (x *UserNotification_MemoMentionPayload) GetMemo() string {
|
||||
@@ -3353,10 +3444,7 @@ const file_api_v1_user_service_proto_rawDesc = "" +
|
||||
"\x17memo_created_timestamps\x18\a \x03(\v2\x1a.google.protobuf.TimestampR\x15memoCreatedTimestamps\x12R\n" +
|
||||
"\x17memo_updated_timestamps\x18\b \x03(\v2\x1a.google.protobuf.TimestampR\x15memoUpdatedTimestamps\x12!\n" +
|
||||
"\fpinned_memos\x18\x05 \x03(\tR\vpinnedMemos\x12(\n" +
|
||||
"\x10total_memo_count\x18\x06 \x01(\x05R\x0etotalMemoCount\x1a;\n" +
|
||||
"\rTagCountEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01\x1a\x8b\x01\n" +
|
||||
"\x10total_memo_count\x18\x06 \x01(\x05R\x0etotalMemoCount\x1a\x8b\x01\n" +
|
||||
"\rMemoTypeStats\x12\x1d\n" +
|
||||
"\n" +
|
||||
"link_count\x18\x01 \x01(\x05R\tlinkCount\x12\x1d\n" +
|
||||
@@ -3365,7 +3453,10 @@ const file_api_v1_user_service_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"todo_count\x18\x03 \x01(\x05R\ttodoCount\x12\x1d\n" +
|
||||
"\n" +
|
||||
"undo_count\x18\x04 \x01(\x05R\tundoCount:?\xeaA<\n" +
|
||||
"undo_count\x18\x04 \x01(\x05R\tundoCount\x1a;\n" +
|
||||
"\rTagCountEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01:?\xeaA<\n" +
|
||||
"\x16memos.api.v1/UserStats\x12\fusers/{user}*\tuserStats2\tuserStatsJ\x04\b\x02\x10\x03R\x17memo_display_timestamps\"D\n" +
|
||||
"\x13GetUserStatsRequest\x12-\n" +
|
||||
"\x04name\x18\x01 \x01(\tB\x19\xe0A\x02\xfaA\x13\n" +
|
||||
@@ -3486,7 +3577,7 @@ const file_api_v1_user_service_proto_rawDesc = "" +
|
||||
"\vupdate_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\n" +
|
||||
"updateTime\x12*\n" +
|
||||
"\x0esigning_secret\x18\x06 \x01(\tB\x03\xe0A\x04R\rsigningSecret\x121\n" +
|
||||
"\x12has_signing_secret\x18\a \x01(\bB\x03\xe0A\x03R\x10hasSigningSecret\"6\n" +
|
||||
"\x12signing_secret_set\x18\a \x01(\bB\x03\xe0A\x03R\x10signingSecretSet\"6\n" +
|
||||
"\x17ListUserWebhooksRequest\x12\x1b\n" +
|
||||
"\x06parent\x18\x01 \x01(\tB\x03\xe0A\x02R\x06parent\"Q\n" +
|
||||
"\x18ListUserWebhooksResponse\x125\n" +
|
||||
@@ -3499,7 +3590,11 @@ const file_api_v1_user_service_proto_rawDesc = "" +
|
||||
"\vupdate_mask\x18\x02 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" +
|
||||
"updateMask\"3\n" +
|
||||
"\x18DeleteUserWebhookRequest\x12\x17\n" +
|
||||
"\x04name\x18\x01 \x01(\tB\x03\xe0A\x02R\x04name\"\xda\b\n" +
|
||||
"\x04name\x18\x01 \x01(\tB\x03\xe0A\x02R\x04name\"=\n" +
|
||||
"\"GetUserWebhookSigningSecretRequest\x12\x17\n" +
|
||||
"\x04name\x18\x01 \x01(\tB\x03\xe0A\x02R\x04name\"L\n" +
|
||||
"#GetUserWebhookSigningSecretResponse\x12%\n" +
|
||||
"\x0esigning_secret\x18\x01 \x01(\tR\rsigningSecret\"\xda\b\n" +
|
||||
"\x10UserNotification\x12\x1a\n" +
|
||||
"\x04name\x18\x01 \x01(\tB\x06\xe0A\x03\xe0A\bR\x04name\x121\n" +
|
||||
"\x06sender\x18\x02 \x01(\tB\x19\xe0A\x03\xfaA\x13\n" +
|
||||
@@ -3549,7 +3644,7 @@ const file_api_v1_user_service_proto_rawDesc = "" +
|
||||
"updateMask\"Z\n" +
|
||||
"\x1dDeleteUserNotificationRequest\x129\n" +
|
||||
"\x04name\x18\x01 \x01(\tB%\xe0A\x02\xfaA\x1f\n" +
|
||||
"\x1dmemos.api.v1/UserNotificationR\x04name2\x82\x1d\n" +
|
||||
"\x1dmemos.api.v1/UserNotificationR\x04name2\xca\x1e\n" +
|
||||
"\vUserService\x12c\n" +
|
||||
"\tListUsers\x12\x1e.memos.api.v1.ListUsersRequest\x1a\x1f.memos.api.v1.ListUsersResponse\"\x15\x82\xd3\xe4\x93\x02\x0f\x12\r/api/v1/users\x12{\n" +
|
||||
"\rBatchGetUsers\x12\".memos.api.v1.BatchGetUsersRequest\x1a#.memos.api.v1.BatchGetUsersResponse\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\"\x16/api/v1/users:batchGet\x12b\n" +
|
||||
@@ -3575,7 +3670,8 @@ const file_api_v1_user_service_proto_rawDesc = "" +
|
||||
"\x10ListUserWebhooks\x12%.memos.api.v1.ListUserWebhooksRequest\x1a&.memos.api.v1.ListUserWebhooksResponse\"2\xdaA\x06parent\x82\xd3\xe4\x93\x02#\x12!/api/v1/{parent=users/*}/webhooks\x12\x9b\x01\n" +
|
||||
"\x11CreateUserWebhook\x12&.memos.api.v1.CreateUserWebhookRequest\x1a\x19.memos.api.v1.UserWebhook\"C\xdaA\x0eparent,webhook\x82\xd3\xe4\x93\x02,:\awebhook\"!/api/v1/{parent=users/*}/webhooks\x12\xa8\x01\n" +
|
||||
"\x11UpdateUserWebhook\x12&.memos.api.v1.UpdateUserWebhookRequest\x1a\x19.memos.api.v1.UserWebhook\"P\xdaA\x13webhook,update_mask\x82\xd3\xe4\x93\x024:\awebhook2)/api/v1/{webhook.name=users/*/webhooks/*}\x12\x85\x01\n" +
|
||||
"\x11DeleteUserWebhook\x12&.memos.api.v1.DeleteUserWebhookRequest\x1a\x16.google.protobuf.Empty\"0\xdaA\x04name\x82\xd3\xe4\x93\x02#*!/api/v1/{name=users/*/webhooks/*}\x12\xa9\x01\n" +
|
||||
"\x11DeleteUserWebhook\x12&.memos.api.v1.DeleteUserWebhookRequest\x1a\x16.google.protobuf.Empty\"0\xdaA\x04name\x82\xd3\xe4\x93\x02#*!/api/v1/{name=users/*/webhooks/*}\x12\xc5\x01\n" +
|
||||
"\x1bGetUserWebhookSigningSecret\x120.memos.api.v1.GetUserWebhookSigningSecretRequest\x1a1.memos.api.v1.GetUserWebhookSigningSecretResponse\"A\xdaA\x04name\x82\xd3\xe4\x93\x024\x122/api/v1/{name=users/*/webhooks/*}:getSigningSecret\x12\xa9\x01\n" +
|
||||
"\x15ListUserNotifications\x12*.memos.api.v1.ListUserNotificationsRequest\x1a+.memos.api.v1.ListUserNotificationsResponse\"7\xdaA\x06parent\x82\xd3\xe4\x93\x02(\x12&/api/v1/{parent=users/*}/notifications\x12\xcb\x01\n" +
|
||||
"\x16UpdateUserNotification\x12+.memos.api.v1.UpdateUserNotificationRequest\x1a\x1e.memos.api.v1.UserNotification\"d\xdaA\x18notification,update_mask\x82\xd3\xe4\x93\x02C:\fnotification23/api/v1/{notification.name=users/*/notifications/*}\x12\x94\x01\n" +
|
||||
"\x16DeleteUserNotification\x12+.memos.api.v1.DeleteUserNotificationRequest\x1a\x16.google.protobuf.Empty\"5\xdaA\x04name\x82\xd3\xe4\x93\x02(*&/api/v1/{name=users/*/notifications/*}B\xa8\x01\n" +
|
||||
@@ -3594,7 +3690,7 @@ func file_api_v1_user_service_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_api_v1_user_service_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||
var file_api_v1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 50)
|
||||
var file_api_v1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 52)
|
||||
var file_api_v1_user_service_proto_goTypes = []any{
|
||||
(User_Role)(0), // 0: memos.api.v1.User.Role
|
||||
(UserSetting_Key)(0), // 1: memos.api.v1.UserSetting.Key
|
||||
@@ -3636,74 +3732,76 @@ var file_api_v1_user_service_proto_goTypes = []any{
|
||||
(*CreateUserWebhookRequest)(nil), // 37: memos.api.v1.CreateUserWebhookRequest
|
||||
(*UpdateUserWebhookRequest)(nil), // 38: memos.api.v1.UpdateUserWebhookRequest
|
||||
(*DeleteUserWebhookRequest)(nil), // 39: memos.api.v1.DeleteUserWebhookRequest
|
||||
(*UserNotification)(nil), // 40: memos.api.v1.UserNotification
|
||||
(*ListUserNotificationsRequest)(nil), // 41: memos.api.v1.ListUserNotificationsRequest
|
||||
(*ListUserNotificationsResponse)(nil), // 42: memos.api.v1.ListUserNotificationsResponse
|
||||
(*UpdateUserNotificationRequest)(nil), // 43: memos.api.v1.UpdateUserNotificationRequest
|
||||
(*DeleteUserNotificationRequest)(nil), // 44: memos.api.v1.DeleteUserNotificationRequest
|
||||
nil, // 45: memos.api.v1.UserStats.TagCountEntry
|
||||
(*UserStats_MemoTypeStats)(nil), // 46: memos.api.v1.UserStats.MemoTypeStats
|
||||
(*UserSetting_GeneralSetting)(nil), // 47: memos.api.v1.UserSetting.GeneralSetting
|
||||
(*UserSetting_TagMetadata)(nil), // 48: memos.api.v1.UserSetting.TagMetadata
|
||||
(*UserSetting_TagsSetting)(nil), // 49: memos.api.v1.UserSetting.TagsSetting
|
||||
(*UserSetting_WebhooksSetting)(nil), // 50: memos.api.v1.UserSetting.WebhooksSetting
|
||||
nil, // 51: memos.api.v1.UserSetting.TagsSetting.TagsEntry
|
||||
(*UserNotification_MemoCommentPayload)(nil), // 52: memos.api.v1.UserNotification.MemoCommentPayload
|
||||
(*UserNotification_MemoMentionPayload)(nil), // 53: memos.api.v1.UserNotification.MemoMentionPayload
|
||||
(State)(0), // 54: memos.api.v1.State
|
||||
(*timestamppb.Timestamp)(nil), // 55: google.protobuf.Timestamp
|
||||
(*fieldmaskpb.FieldMask)(nil), // 56: google.protobuf.FieldMask
|
||||
(*color.Color)(nil), // 57: google.type.Color
|
||||
(*emptypb.Empty)(nil), // 58: google.protobuf.Empty
|
||||
(*GetUserWebhookSigningSecretRequest)(nil), // 40: memos.api.v1.GetUserWebhookSigningSecretRequest
|
||||
(*GetUserWebhookSigningSecretResponse)(nil), // 41: memos.api.v1.GetUserWebhookSigningSecretResponse
|
||||
(*UserNotification)(nil), // 42: memos.api.v1.UserNotification
|
||||
(*ListUserNotificationsRequest)(nil), // 43: memos.api.v1.ListUserNotificationsRequest
|
||||
(*ListUserNotificationsResponse)(nil), // 44: memos.api.v1.ListUserNotificationsResponse
|
||||
(*UpdateUserNotificationRequest)(nil), // 45: memos.api.v1.UpdateUserNotificationRequest
|
||||
(*DeleteUserNotificationRequest)(nil), // 46: memos.api.v1.DeleteUserNotificationRequest
|
||||
(*UserStats_MemoTypeStats)(nil), // 47: memos.api.v1.UserStats.MemoTypeStats
|
||||
nil, // 48: memos.api.v1.UserStats.TagCountEntry
|
||||
(*UserSetting_GeneralSetting)(nil), // 49: memos.api.v1.UserSetting.GeneralSetting
|
||||
(*UserSetting_TagMetadata)(nil), // 50: memos.api.v1.UserSetting.TagMetadata
|
||||
(*UserSetting_TagsSetting)(nil), // 51: memos.api.v1.UserSetting.TagsSetting
|
||||
(*UserSetting_WebhooksSetting)(nil), // 52: memos.api.v1.UserSetting.WebhooksSetting
|
||||
nil, // 53: memos.api.v1.UserSetting.TagsSetting.TagsEntry
|
||||
(*UserNotification_MemoCommentPayload)(nil), // 54: memos.api.v1.UserNotification.MemoCommentPayload
|
||||
(*UserNotification_MemoMentionPayload)(nil), // 55: memos.api.v1.UserNotification.MemoMentionPayload
|
||||
(State)(0), // 56: memos.api.v1.State
|
||||
(*timestamppb.Timestamp)(nil), // 57: google.protobuf.Timestamp
|
||||
(*fieldmaskpb.FieldMask)(nil), // 58: google.protobuf.FieldMask
|
||||
(*color.Color)(nil), // 59: google.type.Color
|
||||
(*emptypb.Empty)(nil), // 60: google.protobuf.Empty
|
||||
}
|
||||
var file_api_v1_user_service_proto_depIdxs = []int32{
|
||||
0, // 0: memos.api.v1.User.role:type_name -> memos.api.v1.User.Role
|
||||
54, // 1: memos.api.v1.User.state:type_name -> memos.api.v1.State
|
||||
55, // 2: memos.api.v1.User.create_time:type_name -> google.protobuf.Timestamp
|
||||
55, // 3: memos.api.v1.User.update_time:type_name -> google.protobuf.Timestamp
|
||||
56, // 1: memos.api.v1.User.state:type_name -> memos.api.v1.State
|
||||
57, // 2: memos.api.v1.User.create_time:type_name -> google.protobuf.Timestamp
|
||||
57, // 3: memos.api.v1.User.update_time:type_name -> google.protobuf.Timestamp
|
||||
4, // 4: memos.api.v1.ListUsersResponse.users:type_name -> memos.api.v1.User
|
||||
4, // 5: memos.api.v1.BatchGetUsersResponse.users:type_name -> memos.api.v1.User
|
||||
56, // 6: memos.api.v1.GetUserRequest.read_mask:type_name -> google.protobuf.FieldMask
|
||||
58, // 6: memos.api.v1.GetUserRequest.read_mask:type_name -> google.protobuf.FieldMask
|
||||
4, // 7: memos.api.v1.CreateUserRequest.user:type_name -> memos.api.v1.User
|
||||
4, // 8: memos.api.v1.UpdateUserRequest.user:type_name -> memos.api.v1.User
|
||||
56, // 9: memos.api.v1.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
46, // 10: memos.api.v1.UserStats.memo_type_stats:type_name -> memos.api.v1.UserStats.MemoTypeStats
|
||||
45, // 11: memos.api.v1.UserStats.tag_count:type_name -> memos.api.v1.UserStats.TagCountEntry
|
||||
55, // 12: memos.api.v1.UserStats.memo_created_timestamps:type_name -> google.protobuf.Timestamp
|
||||
55, // 13: memos.api.v1.UserStats.memo_updated_timestamps:type_name -> google.protobuf.Timestamp
|
||||
54, // 14: memos.api.v1.ListAllUserStatsRequest.state:type_name -> memos.api.v1.State
|
||||
58, // 9: memos.api.v1.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
47, // 10: memos.api.v1.UserStats.memo_type_stats:type_name -> memos.api.v1.UserStats.MemoTypeStats
|
||||
48, // 11: memos.api.v1.UserStats.tag_count:type_name -> memos.api.v1.UserStats.TagCountEntry
|
||||
57, // 12: memos.api.v1.UserStats.memo_created_timestamps:type_name -> google.protobuf.Timestamp
|
||||
57, // 13: memos.api.v1.UserStats.memo_updated_timestamps:type_name -> google.protobuf.Timestamp
|
||||
56, // 14: memos.api.v1.ListAllUserStatsRequest.state:type_name -> memos.api.v1.State
|
||||
13, // 15: memos.api.v1.ListAllUserStatsResponse.stats:type_name -> memos.api.v1.UserStats
|
||||
47, // 16: memos.api.v1.UserSetting.general_setting:type_name -> memos.api.v1.UserSetting.GeneralSetting
|
||||
50, // 17: memos.api.v1.UserSetting.webhooks_setting:type_name -> memos.api.v1.UserSetting.WebhooksSetting
|
||||
49, // 18: memos.api.v1.UserSetting.tags_setting:type_name -> memos.api.v1.UserSetting.TagsSetting
|
||||
49, // 16: memos.api.v1.UserSetting.general_setting:type_name -> memos.api.v1.UserSetting.GeneralSetting
|
||||
52, // 17: memos.api.v1.UserSetting.webhooks_setting:type_name -> memos.api.v1.UserSetting.WebhooksSetting
|
||||
51, // 18: memos.api.v1.UserSetting.tags_setting:type_name -> memos.api.v1.UserSetting.TagsSetting
|
||||
17, // 19: memos.api.v1.UpdateUserSettingRequest.setting:type_name -> memos.api.v1.UserSetting
|
||||
56, // 20: memos.api.v1.UpdateUserSettingRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
58, // 20: memos.api.v1.UpdateUserSettingRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
17, // 21: memos.api.v1.ListUserSettingsResponse.settings:type_name -> memos.api.v1.UserSetting
|
||||
22, // 22: memos.api.v1.ListLinkedIdentitiesResponse.linked_identities:type_name -> memos.api.v1.LinkedIdentity
|
||||
55, // 23: memos.api.v1.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp
|
||||
55, // 24: memos.api.v1.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp
|
||||
55, // 25: memos.api.v1.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp
|
||||
57, // 23: memos.api.v1.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp
|
||||
57, // 24: memos.api.v1.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp
|
||||
57, // 25: memos.api.v1.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp
|
||||
28, // 26: memos.api.v1.ListPersonalAccessTokensResponse.personal_access_tokens:type_name -> memos.api.v1.PersonalAccessToken
|
||||
28, // 27: memos.api.v1.CreatePersonalAccessTokenResponse.personal_access_token:type_name -> memos.api.v1.PersonalAccessToken
|
||||
55, // 28: memos.api.v1.UserWebhook.create_time:type_name -> google.protobuf.Timestamp
|
||||
55, // 29: memos.api.v1.UserWebhook.update_time:type_name -> google.protobuf.Timestamp
|
||||
57, // 28: memos.api.v1.UserWebhook.create_time:type_name -> google.protobuf.Timestamp
|
||||
57, // 29: memos.api.v1.UserWebhook.update_time:type_name -> google.protobuf.Timestamp
|
||||
34, // 30: memos.api.v1.ListUserWebhooksResponse.webhooks:type_name -> memos.api.v1.UserWebhook
|
||||
34, // 31: memos.api.v1.CreateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook
|
||||
34, // 32: memos.api.v1.UpdateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook
|
||||
56, // 33: memos.api.v1.UpdateUserWebhookRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
58, // 33: memos.api.v1.UpdateUserWebhookRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
4, // 34: memos.api.v1.UserNotification.sender_user:type_name -> memos.api.v1.User
|
||||
2, // 35: memos.api.v1.UserNotification.status:type_name -> memos.api.v1.UserNotification.Status
|
||||
55, // 36: memos.api.v1.UserNotification.create_time:type_name -> google.protobuf.Timestamp
|
||||
57, // 36: memos.api.v1.UserNotification.create_time:type_name -> google.protobuf.Timestamp
|
||||
3, // 37: memos.api.v1.UserNotification.type:type_name -> memos.api.v1.UserNotification.Type
|
||||
52, // 38: memos.api.v1.UserNotification.memo_comment:type_name -> memos.api.v1.UserNotification.MemoCommentPayload
|
||||
53, // 39: memos.api.v1.UserNotification.memo_mention:type_name -> memos.api.v1.UserNotification.MemoMentionPayload
|
||||
40, // 40: memos.api.v1.ListUserNotificationsResponse.notifications:type_name -> memos.api.v1.UserNotification
|
||||
40, // 41: memos.api.v1.UpdateUserNotificationRequest.notification:type_name -> memos.api.v1.UserNotification
|
||||
56, // 42: memos.api.v1.UpdateUserNotificationRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
57, // 43: memos.api.v1.UserSetting.TagMetadata.background_color:type_name -> google.type.Color
|
||||
51, // 44: memos.api.v1.UserSetting.TagsSetting.tags:type_name -> memos.api.v1.UserSetting.TagsSetting.TagsEntry
|
||||
54, // 38: memos.api.v1.UserNotification.memo_comment:type_name -> memos.api.v1.UserNotification.MemoCommentPayload
|
||||
55, // 39: memos.api.v1.UserNotification.memo_mention:type_name -> memos.api.v1.UserNotification.MemoMentionPayload
|
||||
42, // 40: memos.api.v1.ListUserNotificationsResponse.notifications:type_name -> memos.api.v1.UserNotification
|
||||
42, // 41: memos.api.v1.UpdateUserNotificationRequest.notification:type_name -> memos.api.v1.UserNotification
|
||||
58, // 42: memos.api.v1.UpdateUserNotificationRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
59, // 43: memos.api.v1.UserSetting.TagMetadata.background_color:type_name -> google.type.Color
|
||||
53, // 44: memos.api.v1.UserSetting.TagsSetting.tags:type_name -> memos.api.v1.UserSetting.TagsSetting.TagsEntry
|
||||
34, // 45: memos.api.v1.UserSetting.WebhooksSetting.webhooks:type_name -> memos.api.v1.UserWebhook
|
||||
48, // 46: memos.api.v1.UserSetting.TagsSetting.TagsEntry.value:type_name -> memos.api.v1.UserSetting.TagMetadata
|
||||
50, // 46: memos.api.v1.UserSetting.TagsSetting.TagsEntry.value:type_name -> memos.api.v1.UserSetting.TagMetadata
|
||||
5, // 47: memos.api.v1.UserService.ListUsers:input_type -> memos.api.v1.ListUsersRequest
|
||||
7, // 48: memos.api.v1.UserService.BatchGetUsers:input_type -> memos.api.v1.BatchGetUsersRequest
|
||||
9, // 49: memos.api.v1.UserService.GetUser:input_type -> memos.api.v1.GetUserRequest
|
||||
@@ -3726,36 +3824,38 @@ var file_api_v1_user_service_proto_depIdxs = []int32{
|
||||
37, // 66: memos.api.v1.UserService.CreateUserWebhook:input_type -> memos.api.v1.CreateUserWebhookRequest
|
||||
38, // 67: memos.api.v1.UserService.UpdateUserWebhook:input_type -> memos.api.v1.UpdateUserWebhookRequest
|
||||
39, // 68: memos.api.v1.UserService.DeleteUserWebhook:input_type -> memos.api.v1.DeleteUserWebhookRequest
|
||||
41, // 69: memos.api.v1.UserService.ListUserNotifications:input_type -> memos.api.v1.ListUserNotificationsRequest
|
||||
43, // 70: memos.api.v1.UserService.UpdateUserNotification:input_type -> memos.api.v1.UpdateUserNotificationRequest
|
||||
44, // 71: memos.api.v1.UserService.DeleteUserNotification:input_type -> memos.api.v1.DeleteUserNotificationRequest
|
||||
6, // 72: memos.api.v1.UserService.ListUsers:output_type -> memos.api.v1.ListUsersResponse
|
||||
8, // 73: memos.api.v1.UserService.BatchGetUsers:output_type -> memos.api.v1.BatchGetUsersResponse
|
||||
4, // 74: memos.api.v1.UserService.GetUser:output_type -> memos.api.v1.User
|
||||
4, // 75: memos.api.v1.UserService.CreateUser:output_type -> memos.api.v1.User
|
||||
4, // 76: memos.api.v1.UserService.UpdateUser:output_type -> memos.api.v1.User
|
||||
58, // 77: memos.api.v1.UserService.DeleteUser:output_type -> google.protobuf.Empty
|
||||
16, // 78: memos.api.v1.UserService.ListAllUserStats:output_type -> memos.api.v1.ListAllUserStatsResponse
|
||||
13, // 79: memos.api.v1.UserService.GetUserStats:output_type -> memos.api.v1.UserStats
|
||||
17, // 80: memos.api.v1.UserService.GetUserSetting:output_type -> memos.api.v1.UserSetting
|
||||
17, // 81: memos.api.v1.UserService.UpdateUserSetting:output_type -> memos.api.v1.UserSetting
|
||||
21, // 82: memos.api.v1.UserService.ListUserSettings:output_type -> memos.api.v1.ListUserSettingsResponse
|
||||
24, // 83: memos.api.v1.UserService.ListLinkedIdentities:output_type -> memos.api.v1.ListLinkedIdentitiesResponse
|
||||
22, // 84: memos.api.v1.UserService.CreateLinkedIdentity:output_type -> memos.api.v1.LinkedIdentity
|
||||
22, // 85: memos.api.v1.UserService.GetLinkedIdentity:output_type -> memos.api.v1.LinkedIdentity
|
||||
58, // 86: memos.api.v1.UserService.DeleteLinkedIdentity:output_type -> google.protobuf.Empty
|
||||
30, // 87: memos.api.v1.UserService.ListPersonalAccessTokens:output_type -> memos.api.v1.ListPersonalAccessTokensResponse
|
||||
32, // 88: memos.api.v1.UserService.CreatePersonalAccessToken:output_type -> memos.api.v1.CreatePersonalAccessTokenResponse
|
||||
58, // 89: memos.api.v1.UserService.DeletePersonalAccessToken:output_type -> google.protobuf.Empty
|
||||
36, // 90: memos.api.v1.UserService.ListUserWebhooks:output_type -> memos.api.v1.ListUserWebhooksResponse
|
||||
34, // 91: memos.api.v1.UserService.CreateUserWebhook:output_type -> memos.api.v1.UserWebhook
|
||||
34, // 92: memos.api.v1.UserService.UpdateUserWebhook:output_type -> memos.api.v1.UserWebhook
|
||||
58, // 93: memos.api.v1.UserService.DeleteUserWebhook:output_type -> google.protobuf.Empty
|
||||
42, // 94: memos.api.v1.UserService.ListUserNotifications:output_type -> memos.api.v1.ListUserNotificationsResponse
|
||||
40, // 95: memos.api.v1.UserService.UpdateUserNotification:output_type -> memos.api.v1.UserNotification
|
||||
58, // 96: memos.api.v1.UserService.DeleteUserNotification:output_type -> google.protobuf.Empty
|
||||
72, // [72:97] is the sub-list for method output_type
|
||||
47, // [47:72] is the sub-list for method input_type
|
||||
40, // 69: memos.api.v1.UserService.GetUserWebhookSigningSecret:input_type -> memos.api.v1.GetUserWebhookSigningSecretRequest
|
||||
43, // 70: memos.api.v1.UserService.ListUserNotifications:input_type -> memos.api.v1.ListUserNotificationsRequest
|
||||
45, // 71: memos.api.v1.UserService.UpdateUserNotification:input_type -> memos.api.v1.UpdateUserNotificationRequest
|
||||
46, // 72: memos.api.v1.UserService.DeleteUserNotification:input_type -> memos.api.v1.DeleteUserNotificationRequest
|
||||
6, // 73: memos.api.v1.UserService.ListUsers:output_type -> memos.api.v1.ListUsersResponse
|
||||
8, // 74: memos.api.v1.UserService.BatchGetUsers:output_type -> memos.api.v1.BatchGetUsersResponse
|
||||
4, // 75: memos.api.v1.UserService.GetUser:output_type -> memos.api.v1.User
|
||||
4, // 76: memos.api.v1.UserService.CreateUser:output_type -> memos.api.v1.User
|
||||
4, // 77: memos.api.v1.UserService.UpdateUser:output_type -> memos.api.v1.User
|
||||
60, // 78: memos.api.v1.UserService.DeleteUser:output_type -> google.protobuf.Empty
|
||||
16, // 79: memos.api.v1.UserService.ListAllUserStats:output_type -> memos.api.v1.ListAllUserStatsResponse
|
||||
13, // 80: memos.api.v1.UserService.GetUserStats:output_type -> memos.api.v1.UserStats
|
||||
17, // 81: memos.api.v1.UserService.GetUserSetting:output_type -> memos.api.v1.UserSetting
|
||||
17, // 82: memos.api.v1.UserService.UpdateUserSetting:output_type -> memos.api.v1.UserSetting
|
||||
21, // 83: memos.api.v1.UserService.ListUserSettings:output_type -> memos.api.v1.ListUserSettingsResponse
|
||||
24, // 84: memos.api.v1.UserService.ListLinkedIdentities:output_type -> memos.api.v1.ListLinkedIdentitiesResponse
|
||||
22, // 85: memos.api.v1.UserService.CreateLinkedIdentity:output_type -> memos.api.v1.LinkedIdentity
|
||||
22, // 86: memos.api.v1.UserService.GetLinkedIdentity:output_type -> memos.api.v1.LinkedIdentity
|
||||
60, // 87: memos.api.v1.UserService.DeleteLinkedIdentity:output_type -> google.protobuf.Empty
|
||||
30, // 88: memos.api.v1.UserService.ListPersonalAccessTokens:output_type -> memos.api.v1.ListPersonalAccessTokensResponse
|
||||
32, // 89: memos.api.v1.UserService.CreatePersonalAccessToken:output_type -> memos.api.v1.CreatePersonalAccessTokenResponse
|
||||
60, // 90: memos.api.v1.UserService.DeletePersonalAccessToken:output_type -> google.protobuf.Empty
|
||||
36, // 91: memos.api.v1.UserService.ListUserWebhooks:output_type -> memos.api.v1.ListUserWebhooksResponse
|
||||
34, // 92: memos.api.v1.UserService.CreateUserWebhook:output_type -> memos.api.v1.UserWebhook
|
||||
34, // 93: memos.api.v1.UserService.UpdateUserWebhook:output_type -> memos.api.v1.UserWebhook
|
||||
60, // 94: memos.api.v1.UserService.DeleteUserWebhook:output_type -> google.protobuf.Empty
|
||||
41, // 95: memos.api.v1.UserService.GetUserWebhookSigningSecret:output_type -> memos.api.v1.GetUserWebhookSigningSecretResponse
|
||||
44, // 96: memos.api.v1.UserService.ListUserNotifications:output_type -> memos.api.v1.ListUserNotificationsResponse
|
||||
42, // 97: memos.api.v1.UserService.UpdateUserNotification:output_type -> memos.api.v1.UserNotification
|
||||
60, // 98: memos.api.v1.UserService.DeleteUserNotification:output_type -> google.protobuf.Empty
|
||||
73, // [73:99] is the sub-list for method output_type
|
||||
47, // [47:73] is the sub-list for method input_type
|
||||
47, // [47:47] is the sub-list for extension type_name
|
||||
47, // [47:47] is the sub-list for extension extendee
|
||||
0, // [0:47] is the sub-list for field type_name
|
||||
@@ -3772,7 +3872,7 @@ func file_api_v1_user_service_proto_init() {
|
||||
(*UserSetting_WebhooksSetting_)(nil),
|
||||
(*UserSetting_TagsSetting_)(nil),
|
||||
}
|
||||
file_api_v1_user_service_proto_msgTypes[36].OneofWrappers = []any{
|
||||
file_api_v1_user_service_proto_msgTypes[38].OneofWrappers = []any{
|
||||
(*UserNotification_MemoComment)(nil),
|
||||
(*UserNotification_MemoMention)(nil),
|
||||
}
|
||||
@@ -3782,7 +3882,7 @@ func file_api_v1_user_service_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_user_service_proto_rawDesc), len(file_api_v1_user_service_proto_rawDesc)),
|
||||
NumEnums: 4,
|
||||
NumMessages: 50,
|
||||
NumMessages: 52,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -1075,6 +1075,45 @@ func local_request_UserService_DeleteUserWebhook_0(ctx context.Context, marshale
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_UserService_GetUserWebhookSigningSecret_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq GetUserWebhookSigningSecretRequest
|
||||
metadata runtime.ServerMetadata
|
||||
err error
|
||||
)
|
||||
if req.Body != nil {
|
||||
_, _ = io.Copy(io.Discard, req.Body)
|
||||
}
|
||||
val, ok := pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
protoReq.Name, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
msg, err := client.GetUserWebhookSigningSecret(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_UserService_GetUserWebhookSigningSecret_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq GetUserWebhookSigningSecretRequest
|
||||
metadata runtime.ServerMetadata
|
||||
err error
|
||||
)
|
||||
val, ok := pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
protoReq.Name, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
msg, err := server.GetUserWebhookSigningSecret(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
var filter_UserService_ListUserNotifications_0 = &utilities.DoubleArray{Encoding: map[string]int{"parent": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
|
||||
func request_UserService_ListUserNotifications_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
@@ -1694,6 +1733,26 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
|
||||
}
|
||||
forward_UserService_DeleteUserWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_UserService_GetUserWebhookSigningSecret_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserWebhookSigningSecret", runtime.WithHTTPPathPattern("/api/v1/{name=users/*/webhooks/*}:getSigningSecret"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_GetUserWebhookSigningSecret_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_UserService_GetUserWebhookSigningSecret_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_UserService_ListUserNotifications_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -2168,6 +2227,23 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
||||
}
|
||||
forward_UserService_DeleteUserWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_UserService_GetUserWebhookSigningSecret_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserWebhookSigningSecret", runtime.WithHTTPPathPattern("/api/v1/{name=users/*/webhooks/*}:getSigningSecret"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_GetUserWebhookSigningSecret_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_UserService_GetUserWebhookSigningSecret_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_UserService_ListUserNotifications_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -2223,57 +2299,59 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_UserService_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, ""))
|
||||
pattern_UserService_BatchGetUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "batchGet"))
|
||||
pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, ""))
|
||||
pattern_UserService_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, ""))
|
||||
pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "user.name"}, ""))
|
||||
pattern_UserService_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, ""))
|
||||
pattern_UserService_ListAllUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "stats"))
|
||||
pattern_UserService_GetUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, "getStats"))
|
||||
pattern_UserService_GetUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "settings", "name"}, ""))
|
||||
pattern_UserService_UpdateUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "settings", "setting.name"}, ""))
|
||||
pattern_UserService_ListUserSettings_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "settings"}, ""))
|
||||
pattern_UserService_ListLinkedIdentities_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "linkedIdentities"}, ""))
|
||||
pattern_UserService_CreateLinkedIdentity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "linkedIdentities"}, ""))
|
||||
pattern_UserService_GetLinkedIdentity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "linkedIdentities", "name"}, ""))
|
||||
pattern_UserService_DeleteLinkedIdentity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "linkedIdentities", "name"}, ""))
|
||||
pattern_UserService_ListPersonalAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "personalAccessTokens"}, ""))
|
||||
pattern_UserService_CreatePersonalAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "personalAccessTokens"}, ""))
|
||||
pattern_UserService_DeletePersonalAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "personalAccessTokens", "name"}, ""))
|
||||
pattern_UserService_ListUserWebhooks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "webhooks"}, ""))
|
||||
pattern_UserService_CreateUserWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "webhooks"}, ""))
|
||||
pattern_UserService_UpdateUserWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "webhooks", "webhook.name"}, ""))
|
||||
pattern_UserService_DeleteUserWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "webhooks", "name"}, ""))
|
||||
pattern_UserService_ListUserNotifications_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "notifications"}, ""))
|
||||
pattern_UserService_UpdateUserNotification_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "notifications", "notification.name"}, ""))
|
||||
pattern_UserService_DeleteUserNotification_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "notifications", "name"}, ""))
|
||||
pattern_UserService_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, ""))
|
||||
pattern_UserService_BatchGetUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "batchGet"))
|
||||
pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, ""))
|
||||
pattern_UserService_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, ""))
|
||||
pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "user.name"}, ""))
|
||||
pattern_UserService_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, ""))
|
||||
pattern_UserService_ListAllUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "stats"))
|
||||
pattern_UserService_GetUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, "getStats"))
|
||||
pattern_UserService_GetUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "settings", "name"}, ""))
|
||||
pattern_UserService_UpdateUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "settings", "setting.name"}, ""))
|
||||
pattern_UserService_ListUserSettings_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "settings"}, ""))
|
||||
pattern_UserService_ListLinkedIdentities_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "linkedIdentities"}, ""))
|
||||
pattern_UserService_CreateLinkedIdentity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "linkedIdentities"}, ""))
|
||||
pattern_UserService_GetLinkedIdentity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "linkedIdentities", "name"}, ""))
|
||||
pattern_UserService_DeleteLinkedIdentity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "linkedIdentities", "name"}, ""))
|
||||
pattern_UserService_ListPersonalAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "personalAccessTokens"}, ""))
|
||||
pattern_UserService_CreatePersonalAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "personalAccessTokens"}, ""))
|
||||
pattern_UserService_DeletePersonalAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "personalAccessTokens", "name"}, ""))
|
||||
pattern_UserService_ListUserWebhooks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "webhooks"}, ""))
|
||||
pattern_UserService_CreateUserWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "webhooks"}, ""))
|
||||
pattern_UserService_UpdateUserWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "webhooks", "webhook.name"}, ""))
|
||||
pattern_UserService_DeleteUserWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "webhooks", "name"}, ""))
|
||||
pattern_UserService_GetUserWebhookSigningSecret_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "webhooks", "name"}, "getSigningSecret"))
|
||||
pattern_UserService_ListUserNotifications_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "notifications"}, ""))
|
||||
pattern_UserService_UpdateUserNotification_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "notifications", "notification.name"}, ""))
|
||||
pattern_UserService_DeleteUserNotification_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "notifications", "name"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_UserService_ListUsers_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_BatchGetUsers_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_CreateUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListAllUserStats_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUserStats_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUserSetting_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUserSetting_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListUserSettings_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListLinkedIdentities_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_CreateLinkedIdentity_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetLinkedIdentity_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteLinkedIdentity_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListPersonalAccessTokens_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_CreatePersonalAccessToken_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeletePersonalAccessToken_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListUserWebhooks_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_CreateUserWebhook_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUserWebhook_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteUserWebhook_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListUserNotifications_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUserNotification_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteUserNotification_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListUsers_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_BatchGetUsers_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_CreateUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListAllUserStats_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUserStats_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUserSetting_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUserSetting_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListUserSettings_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListLinkedIdentities_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_CreateLinkedIdentity_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetLinkedIdentity_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteLinkedIdentity_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListPersonalAccessTokens_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_CreatePersonalAccessToken_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeletePersonalAccessToken_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListUserWebhooks_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_CreateUserWebhook_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUserWebhook_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteUserWebhook_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUserWebhookSigningSecret_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListUserNotifications_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUserNotification_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteUserNotification_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
@@ -20,31 +20,32 @@ import (
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
UserService_ListUsers_FullMethodName = "/memos.api.v1.UserService/ListUsers"
|
||||
UserService_BatchGetUsers_FullMethodName = "/memos.api.v1.UserService/BatchGetUsers"
|
||||
UserService_GetUser_FullMethodName = "/memos.api.v1.UserService/GetUser"
|
||||
UserService_CreateUser_FullMethodName = "/memos.api.v1.UserService/CreateUser"
|
||||
UserService_UpdateUser_FullMethodName = "/memos.api.v1.UserService/UpdateUser"
|
||||
UserService_DeleteUser_FullMethodName = "/memos.api.v1.UserService/DeleteUser"
|
||||
UserService_ListAllUserStats_FullMethodName = "/memos.api.v1.UserService/ListAllUserStats"
|
||||
UserService_GetUserStats_FullMethodName = "/memos.api.v1.UserService/GetUserStats"
|
||||
UserService_GetUserSetting_FullMethodName = "/memos.api.v1.UserService/GetUserSetting"
|
||||
UserService_UpdateUserSetting_FullMethodName = "/memos.api.v1.UserService/UpdateUserSetting"
|
||||
UserService_ListUserSettings_FullMethodName = "/memos.api.v1.UserService/ListUserSettings"
|
||||
UserService_ListLinkedIdentities_FullMethodName = "/memos.api.v1.UserService/ListLinkedIdentities"
|
||||
UserService_CreateLinkedIdentity_FullMethodName = "/memos.api.v1.UserService/CreateLinkedIdentity"
|
||||
UserService_GetLinkedIdentity_FullMethodName = "/memos.api.v1.UserService/GetLinkedIdentity"
|
||||
UserService_DeleteLinkedIdentity_FullMethodName = "/memos.api.v1.UserService/DeleteLinkedIdentity"
|
||||
UserService_ListPersonalAccessTokens_FullMethodName = "/memos.api.v1.UserService/ListPersonalAccessTokens"
|
||||
UserService_CreatePersonalAccessToken_FullMethodName = "/memos.api.v1.UserService/CreatePersonalAccessToken"
|
||||
UserService_DeletePersonalAccessToken_FullMethodName = "/memos.api.v1.UserService/DeletePersonalAccessToken"
|
||||
UserService_ListUserWebhooks_FullMethodName = "/memos.api.v1.UserService/ListUserWebhooks"
|
||||
UserService_CreateUserWebhook_FullMethodName = "/memos.api.v1.UserService/CreateUserWebhook"
|
||||
UserService_UpdateUserWebhook_FullMethodName = "/memos.api.v1.UserService/UpdateUserWebhook"
|
||||
UserService_DeleteUserWebhook_FullMethodName = "/memos.api.v1.UserService/DeleteUserWebhook"
|
||||
UserService_ListUserNotifications_FullMethodName = "/memos.api.v1.UserService/ListUserNotifications"
|
||||
UserService_UpdateUserNotification_FullMethodName = "/memos.api.v1.UserService/UpdateUserNotification"
|
||||
UserService_DeleteUserNotification_FullMethodName = "/memos.api.v1.UserService/DeleteUserNotification"
|
||||
UserService_ListUsers_FullMethodName = "/memos.api.v1.UserService/ListUsers"
|
||||
UserService_BatchGetUsers_FullMethodName = "/memos.api.v1.UserService/BatchGetUsers"
|
||||
UserService_GetUser_FullMethodName = "/memos.api.v1.UserService/GetUser"
|
||||
UserService_CreateUser_FullMethodName = "/memos.api.v1.UserService/CreateUser"
|
||||
UserService_UpdateUser_FullMethodName = "/memos.api.v1.UserService/UpdateUser"
|
||||
UserService_DeleteUser_FullMethodName = "/memos.api.v1.UserService/DeleteUser"
|
||||
UserService_ListAllUserStats_FullMethodName = "/memos.api.v1.UserService/ListAllUserStats"
|
||||
UserService_GetUserStats_FullMethodName = "/memos.api.v1.UserService/GetUserStats"
|
||||
UserService_GetUserSetting_FullMethodName = "/memos.api.v1.UserService/GetUserSetting"
|
||||
UserService_UpdateUserSetting_FullMethodName = "/memos.api.v1.UserService/UpdateUserSetting"
|
||||
UserService_ListUserSettings_FullMethodName = "/memos.api.v1.UserService/ListUserSettings"
|
||||
UserService_ListLinkedIdentities_FullMethodName = "/memos.api.v1.UserService/ListLinkedIdentities"
|
||||
UserService_CreateLinkedIdentity_FullMethodName = "/memos.api.v1.UserService/CreateLinkedIdentity"
|
||||
UserService_GetLinkedIdentity_FullMethodName = "/memos.api.v1.UserService/GetLinkedIdentity"
|
||||
UserService_DeleteLinkedIdentity_FullMethodName = "/memos.api.v1.UserService/DeleteLinkedIdentity"
|
||||
UserService_ListPersonalAccessTokens_FullMethodName = "/memos.api.v1.UserService/ListPersonalAccessTokens"
|
||||
UserService_CreatePersonalAccessToken_FullMethodName = "/memos.api.v1.UserService/CreatePersonalAccessToken"
|
||||
UserService_DeletePersonalAccessToken_FullMethodName = "/memos.api.v1.UserService/DeletePersonalAccessToken"
|
||||
UserService_ListUserWebhooks_FullMethodName = "/memos.api.v1.UserService/ListUserWebhooks"
|
||||
UserService_CreateUserWebhook_FullMethodName = "/memos.api.v1.UserService/CreateUserWebhook"
|
||||
UserService_UpdateUserWebhook_FullMethodName = "/memos.api.v1.UserService/UpdateUserWebhook"
|
||||
UserService_DeleteUserWebhook_FullMethodName = "/memos.api.v1.UserService/DeleteUserWebhook"
|
||||
UserService_GetUserWebhookSigningSecret_FullMethodName = "/memos.api.v1.UserService/GetUserWebhookSigningSecret"
|
||||
UserService_ListUserNotifications_FullMethodName = "/memos.api.v1.UserService/ListUserNotifications"
|
||||
UserService_UpdateUserNotification_FullMethodName = "/memos.api.v1.UserService/UpdateUserNotification"
|
||||
UserService_DeleteUserNotification_FullMethodName = "/memos.api.v1.UserService/DeleteUserNotification"
|
||||
)
|
||||
|
||||
// UserServiceClient is the client API for UserService service.
|
||||
@@ -98,6 +99,10 @@ type UserServiceClient interface {
|
||||
UpdateUserWebhook(ctx context.Context, in *UpdateUserWebhookRequest, opts ...grpc.CallOption) (*UserWebhook, error)
|
||||
// DeleteUserWebhook deletes a webhook for a user.
|
||||
DeleteUserWebhook(ctx context.Context, in *DeleteUserWebhookRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
// GetUserWebhookSigningSecret returns the signing secret for a webhook.
|
||||
// The secret is returned only through this explicit, owner-gated call; it is
|
||||
// never included in List/Create/Update responses.
|
||||
GetUserWebhookSigningSecret(ctx context.Context, in *GetUserWebhookSigningSecretRequest, opts ...grpc.CallOption) (*GetUserWebhookSigningSecretResponse, error)
|
||||
// ListUserNotifications lists notifications for a user.
|
||||
ListUserNotifications(ctx context.Context, in *ListUserNotificationsRequest, opts ...grpc.CallOption) (*ListUserNotificationsResponse, error)
|
||||
// UpdateUserNotification updates a notification.
|
||||
@@ -334,6 +339,16 @@ func (c *userServiceClient) DeleteUserWebhook(ctx context.Context, in *DeleteUse
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) GetUserWebhookSigningSecret(ctx context.Context, in *GetUserWebhookSigningSecretRequest, opts ...grpc.CallOption) (*GetUserWebhookSigningSecretResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetUserWebhookSigningSecretResponse)
|
||||
err := c.cc.Invoke(ctx, UserService_GetUserWebhookSigningSecret_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) ListUserNotifications(ctx context.Context, in *ListUserNotificationsRequest, opts ...grpc.CallOption) (*ListUserNotificationsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListUserNotificationsResponse)
|
||||
@@ -415,6 +430,10 @@ type UserServiceServer interface {
|
||||
UpdateUserWebhook(context.Context, *UpdateUserWebhookRequest) (*UserWebhook, error)
|
||||
// DeleteUserWebhook deletes a webhook for a user.
|
||||
DeleteUserWebhook(context.Context, *DeleteUserWebhookRequest) (*emptypb.Empty, error)
|
||||
// GetUserWebhookSigningSecret returns the signing secret for a webhook.
|
||||
// The secret is returned only through this explicit, owner-gated call; it is
|
||||
// never included in List/Create/Update responses.
|
||||
GetUserWebhookSigningSecret(context.Context, *GetUserWebhookSigningSecretRequest) (*GetUserWebhookSigningSecretResponse, error)
|
||||
// ListUserNotifications lists notifications for a user.
|
||||
ListUserNotifications(context.Context, *ListUserNotificationsRequest) (*ListUserNotificationsResponse, error)
|
||||
// UpdateUserNotification updates a notification.
|
||||
@@ -497,6 +516,9 @@ func (UnimplementedUserServiceServer) UpdateUserWebhook(context.Context, *Update
|
||||
func (UnimplementedUserServiceServer) DeleteUserWebhook(context.Context, *DeleteUserWebhookRequest) (*emptypb.Empty, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method DeleteUserWebhook not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) GetUserWebhookSigningSecret(context.Context, *GetUserWebhookSigningSecretRequest) (*GetUserWebhookSigningSecretResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetUserWebhookSigningSecret not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) ListUserNotifications(context.Context, *ListUserNotificationsRequest) (*ListUserNotificationsResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListUserNotifications not implemented")
|
||||
}
|
||||
@@ -923,6 +945,24 @@ func _UserService_DeleteUserWebhook_Handler(srv interface{}, ctx context.Context
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_GetUserWebhookSigningSecret_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetUserWebhookSigningSecretRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).GetUserWebhookSigningSecret(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: UserService_GetUserWebhookSigningSecret_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).GetUserWebhookSigningSecret(ctx, req.(*GetUserWebhookSigningSecretRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_ListUserNotifications_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListUserNotificationsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -1072,6 +1112,10 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "DeleteUserWebhook",
|
||||
Handler: _UserService_DeleteUserWebhook_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetUserWebhookSigningSecret",
|
||||
Handler: _UserService_GetUserWebhookSigningSecret_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListUserNotifications",
|
||||
Handler: _UserService_ListUserNotifications_Handler,
|
||||
|
||||
+43
-2
@@ -2209,6 +2209,41 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
/api/v1/users/{user}/webhooks/{webhook}:getSigningSecret:
|
||||
get:
|
||||
tags:
|
||||
- UserService
|
||||
description: |-
|
||||
GetUserWebhookSigningSecret returns the signing secret for a webhook.
|
||||
The secret is returned only through this explicit, owner-gated call; it is
|
||||
never included in List/Create/Update responses.
|
||||
operationId: UserService_GetUserWebhookSigningSecret
|
||||
parameters:
|
||||
- name: user
|
||||
in: path
|
||||
description: The user id.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: webhook
|
||||
in: path
|
||||
description: The webhook id.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GetUserWebhookSigningSecretResponse'
|
||||
default:
|
||||
description: Default error response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
/api/v1/users/{user}:getStats:
|
||||
get:
|
||||
tags:
|
||||
@@ -2644,6 +2679,12 @@ components:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/User'
|
||||
description: The authenticated user's information.
|
||||
GetUserWebhookSigningSecretResponse:
|
||||
type: object
|
||||
properties:
|
||||
signingSecret:
|
||||
type: string
|
||||
description: The signing secret, in the Standard Webhooks "whsec_<base64>" form.
|
||||
GoogleProtobufAny:
|
||||
type: object
|
||||
properties:
|
||||
@@ -3993,10 +4034,10 @@ components:
|
||||
description: |-
|
||||
Optional. Signing secret used to HMAC-SHA256 sign the webhook request body.
|
||||
This field is input-only; it is never returned in responses.
|
||||
hasSigningSecret:
|
||||
signingSecretSet:
|
||||
readOnly: true
|
||||
type: boolean
|
||||
description: Whether this webhook has a signing secret configured.
|
||||
description: Whether a signing secret is configured for this webhook.
|
||||
description: UserWebhook represents a webhook owned by a user.
|
||||
tags:
|
||||
- name: AIService
|
||||
|
||||
@@ -269,6 +269,14 @@ func (s *ConnectServiceHandler) DeleteUserWebhook(ctx context.Context, req *conn
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetUserWebhookSigningSecret(ctx context.Context, req *connect.Request[v1pb.GetUserWebhookSigningSecretRequest]) (*connect.Response[v1pb.GetUserWebhookSigningSecretResponse], error) {
|
||||
resp, err := s.APIV1Service.GetUserWebhookSigningSecret(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListUserNotifications(ctx context.Context, req *connect.Request[v1pb.ListUserNotificationsRequest]) (*connect.Response[v1pb.ListUserNotificationsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListUserNotifications(ctx, req.Msg)
|
||||
if err != nil {
|
||||
|
||||
@@ -1095,7 +1095,16 @@ func (s *APIV1Service) CreateUserWebhook(ctx context.Context, request *v1pb.Crea
|
||||
if err := webhook.ValidateURL(strings.TrimSpace(request.Webhook.Url)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := webhook.ValidateSigningSecret(strings.TrimSpace(request.Webhook.SigningSecret)); err != nil {
|
||||
// The signing secret is generated server-side so it always meets the Standard
|
||||
// Webhooks length requirement. A client-supplied secret is still accepted (and
|
||||
// validated) for backward compatibility.
|
||||
signingSecret := strings.TrimSpace(request.Webhook.SigningSecret)
|
||||
if signingSecret == "" {
|
||||
signingSecret, err = webhook.GenerateSigningSecret()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to generate signing secret: %v", err)
|
||||
}
|
||||
} else if err := webhook.ValidateSigningSecret(signingSecret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1104,7 +1113,7 @@ func (s *APIV1Service) CreateUserWebhook(ctx context.Context, request *v1pb.Crea
|
||||
Id: webhookID,
|
||||
Title: request.Webhook.DisplayName,
|
||||
Url: strings.TrimSpace(request.Webhook.Url),
|
||||
SigningSecret: strings.TrimSpace(request.Webhook.SigningSecret),
|
||||
SigningSecret: signingSecret,
|
||||
}
|
||||
|
||||
err = s.Store.AddUserWebhook(ctx, userID, webhook)
|
||||
@@ -1259,6 +1268,34 @@ func (s *APIV1Service) DeleteUserWebhook(ctx context.Context, request *v1pb.Dele
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
// GetUserWebhookSigningSecret reveals the signing secret for a single webhook.
|
||||
// This is the only endpoint that returns the secret value; it is gated to the
|
||||
// webhook owner (or an admin) and the secret is never included in list/create/update responses.
|
||||
func (s *APIV1Service) GetUserWebhookSigningSecret(ctx context.Context, request *v1pb.GetUserWebhookSigningSecretRequest) (*v1pb.GetUserWebhookSigningSecretResponse, error) {
|
||||
user, webhookID, err := s.resolveUserAndWebhookIDFromName(ctx, request.Name)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid webhook name: %v", err)
|
||||
}
|
||||
userID := user.ID
|
||||
|
||||
if _, err := s.authorizeUserResourceAccess(ctx, userID, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
webhooks, err := s.Store.GetUserWebhooks(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get user webhooks: %v", err)
|
||||
}
|
||||
|
||||
for _, webhook := range webhooks {
|
||||
if webhook.Id == webhookID {
|
||||
return &v1pb.GetUserWebhookSigningSecretResponse{SigningSecret: webhook.SigningSecret}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, status.Errorf(codes.NotFound, "webhook not found")
|
||||
}
|
||||
|
||||
// Helper functions for webhook operations
|
||||
|
||||
// generateUserWebhookID generates a unique ID for user webhooks.
|
||||
@@ -1274,7 +1311,7 @@ func convertUserWebhookFromUserSetting(webhook *storepb.WebhooksUserSetting_Webh
|
||||
Name: fmt.Sprintf("%s/webhooks/%s", BuildUserName(user.Username), webhook.Id),
|
||||
Url: webhook.Url,
|
||||
DisplayName: webhook.Title,
|
||||
HasSigningSecret: webhook.SigningSecret != "",
|
||||
SigningSecretSet: webhook.SigningSecret != "",
|
||||
// Note: create_time and update_time are not available in the user setting webhook structure
|
||||
// This is a limitation of storing webhooks in user settings vs the dedicated webhook table
|
||||
}
|
||||
@@ -1474,7 +1511,7 @@ func convertUserSettingFromStore(storeSetting *storepb.UserSetting, user *store.
|
||||
Name: fmt.Sprintf("%s/webhooks/%s", BuildUserName(user.Username), webhook.Id),
|
||||
Url: webhook.Url,
|
||||
DisplayName: webhook.Title,
|
||||
HasSigningSecret: webhook.SigningSecret != "",
|
||||
SigningSecretSet: webhook.SigningSecret != "",
|
||||
}
|
||||
apiWebhooks = append(apiWebhooks, apiWebhook)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
v1pb "github.com/usememos/memos/proto/gen/api/v1"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
@@ -26,5 +31,43 @@ func TestConvertUserWebhookFromUserSettingOmitsSigningSecret(t *testing.T) {
|
||||
require.Equal(t, "My Webhook", apiWebhook.DisplayName)
|
||||
require.Equal(t, "https://example.com/postreceive", apiWebhook.Url)
|
||||
require.Empty(t, apiWebhook.SigningSecret, "signing secret must never be returned in API responses")
|
||||
require.True(t, apiWebhook.HasSigningSecret, "has_signing_secret must be true when secret is configured")
|
||||
require.True(t, apiWebhook.SigningSecretSet, "signing_secret_set must be true when secret is configured")
|
||||
}
|
||||
|
||||
// TestUserWebhookSigningSecretLifecycle covers the reveal-later flow: a webhook
|
||||
// created without a secret is auto-assigned one server-side (exposed only via the
|
||||
// signing_secret_set flag), the owner can reveal the value, and a non-owner cannot.
|
||||
func TestUserWebhookSigningSecretLifecycle(t *testing.T) {
|
||||
svc := newIntegrationService(t)
|
||||
ctx := context.Background()
|
||||
|
||||
// First user initializes the store as host/admin; the test actors are regular users.
|
||||
_, err := svc.Store.CreateUser(ctx, &store.User{Username: "host", Role: store.RoleAdmin, Email: "host@example.com"})
|
||||
require.NoError(t, err)
|
||||
owner, err := svc.Store.CreateUser(ctx, &store.User{Username: "owner", Role: store.RoleUser, Email: "owner@example.com"})
|
||||
require.NoError(t, err)
|
||||
other, err := svc.Store.CreateUser(ctx, &store.User{Username: "other", Role: store.RoleUser, Email: "other@example.com"})
|
||||
require.NoError(t, err)
|
||||
|
||||
ownerCtx := userCtx(ctx, owner.ID)
|
||||
otherCtx := userCtx(ctx, other.ID)
|
||||
|
||||
// Create without supplying a secret -> the server generates one.
|
||||
created, err := svc.CreateUserWebhook(ownerCtx, &v1pb.CreateUserWebhookRequest{
|
||||
Parent: "users/owner",
|
||||
Webhook: &v1pb.UserWebhook{DisplayName: "deploy", Url: "https://example.com/postreceive"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.True(t, created.SigningSecretSet, "create must auto-generate a signing secret")
|
||||
require.Empty(t, created.SigningSecret, "create response must never carry the secret value")
|
||||
|
||||
// The owner can reveal the generated value.
|
||||
revealed, err := svc.GetUserWebhookSigningSecret(ownerCtx, &v1pb.GetUserWebhookSigningSecretRequest{Name: created.Name})
|
||||
require.NoError(t, err)
|
||||
require.True(t, strings.HasPrefix(revealed.SigningSecret, "whsec_"), "revealed secret must be in whsec_ form")
|
||||
|
||||
// A non-owner, non-admin user cannot reveal it.
|
||||
_, err = svc.GetUserWebhookSigningSecret(otherCtx, &v1pb.GetUserWebhookSigningSecretRequest{Name: created.Name})
|
||||
require.Error(t, err)
|
||||
require.Equal(t, codes.PermissionDenied, status.Code(err), "non-owner must be denied")
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { create } from "@bufbuild/protobuf";
|
||||
import { FieldMaskSchema } from "@bufbuild/protobuf/wkt";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { CheckIcon, CopyIcon, Trash2Icon } from "lucide-react";
|
||||
import { CheckIcon, CopyIcon, EyeIcon } from "lucide-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -24,20 +24,18 @@ interface Props {
|
||||
interface State {
|
||||
displayName: string;
|
||||
url: string;
|
||||
signingSecret: string | undefined;
|
||||
}
|
||||
|
||||
function CreateWebhookDialog({ open, onOpenChange, webhookName, onSuccess }: Props) {
|
||||
const t = useTranslate();
|
||||
const currentUser = useCurrentUser();
|
||||
const isCreating = webhookName === undefined;
|
||||
const [state, setState] = useState<State>({
|
||||
displayName: "",
|
||||
url: "",
|
||||
signingSecret: isCreating ? "" : undefined,
|
||||
});
|
||||
const [state, setState] = useState<State>({ displayName: "", url: "" });
|
||||
const requestState = useLoading(false);
|
||||
const secretState = useLoading(false);
|
||||
const [hasExistingSecret, setHasExistingSecret] = useState(false);
|
||||
const [revealedSecret, setRevealedSecret] = useState<string | undefined>(undefined);
|
||||
const [createdSecret, setCreatedSecret] = useState<string | undefined>(undefined);
|
||||
const [secretCopied, setSecretCopied] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -49,12 +47,8 @@ function CreateWebhookDialog({ open, onOpenChange, webhookName, onSuccess }: Pro
|
||||
.then((response) => {
|
||||
const webhook = response.webhooks.find((w) => w.name === webhookName);
|
||||
if (webhook) {
|
||||
setState({
|
||||
displayName: webhook.displayName,
|
||||
url: webhook.url,
|
||||
signingSecret: undefined,
|
||||
});
|
||||
setHasExistingSecret(webhook.hasSigningSecret);
|
||||
setState({ displayName: webhook.displayName, url: webhook.url });
|
||||
setHasExistingSecret(webhook.signingSecretSet);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -62,62 +56,67 @@ function CreateWebhookDialog({ open, onOpenChange, webhookName, onSuccess }: Pro
|
||||
|
||||
useEffect(() => {
|
||||
if (open && isCreating) {
|
||||
setState({
|
||||
displayName: "",
|
||||
url: "",
|
||||
signingSecret: "",
|
||||
});
|
||||
setState({ displayName: "", url: "" });
|
||||
setHasExistingSecret(false);
|
||||
setRevealedSecret(undefined);
|
||||
setCreatedSecret(undefined);
|
||||
setSecretCopied(false);
|
||||
}
|
||||
}, [open, isCreating]);
|
||||
|
||||
const setPartialState = (partialState: Partial<State>) => {
|
||||
setState({
|
||||
...state,
|
||||
...partialState,
|
||||
});
|
||||
};
|
||||
|
||||
const handleTitleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setPartialState({
|
||||
displayName: e.target.value,
|
||||
});
|
||||
setState((prev) => ({ ...prev, displayName: e.target.value }));
|
||||
};
|
||||
|
||||
const handleUrlInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setPartialState({
|
||||
url: e.target.value,
|
||||
});
|
||||
setState((prev) => ({ ...prev, url: e.target.value }));
|
||||
};
|
||||
|
||||
const handleGenerateAndCopy = () => {
|
||||
const bytes = crypto.getRandomValues(new Uint8Array(32));
|
||||
const secret = "whsec_" + btoa(String.fromCharCode(...bytes));
|
||||
setPartialState({ signingSecret: secret });
|
||||
const handleCopySecret = (secret: string) => {
|
||||
copy(secret);
|
||||
setSecretCopied(true);
|
||||
setTimeout(() => setSecretCopied(false), 2000);
|
||||
};
|
||||
|
||||
const handleClearSecret = () => {
|
||||
setPartialState({ signingSecret: "" });
|
||||
const handleRevealSecret = async () => {
|
||||
if (!webhookName) return;
|
||||
try {
|
||||
secretState.setLoading();
|
||||
const { signingSecret } = await userServiceClient.getUserWebhookSigningSecret({ name: webhookName });
|
||||
setRevealedSecret(signingSecret);
|
||||
secretState.setFinish();
|
||||
} catch (error: unknown) {
|
||||
handleError(error, toast.error, { context: "Reveal signing secret", onError: () => secretState.setError() });
|
||||
}
|
||||
};
|
||||
|
||||
const normalizedSigningSecret = state.signingSecret?.trim() ?? "";
|
||||
// Lets a pre-existing webhook that has no secret adopt one. The secret is
|
||||
// persisted immediately and revealed so the user can copy it once.
|
||||
const handleGenerateSecret = async () => {
|
||||
if (!webhookName) return;
|
||||
const bytes = crypto.getRandomValues(new Uint8Array(32));
|
||||
const secret = "whsec_" + btoa(String.fromCharCode(...bytes));
|
||||
try {
|
||||
secretState.setLoading();
|
||||
await userServiceClient.updateUserWebhook({
|
||||
webhook: { name: webhookName, signingSecret: secret },
|
||||
updateMask: create(FieldMaskSchema, { paths: ["signing_secret"] }),
|
||||
});
|
||||
setHasExistingSecret(true);
|
||||
setRevealedSecret(secret);
|
||||
handleCopySecret(secret);
|
||||
secretState.setFinish();
|
||||
} catch (error: unknown) {
|
||||
handleError(error, toast.error, { context: "Generate signing secret", onError: () => secretState.setError() });
|
||||
}
|
||||
};
|
||||
|
||||
const getPendingLabel = () => {
|
||||
const prefix = `${t("setting.webhook.create-dialog.signing-secret-pending")}: `;
|
||||
if (state.signingSecret === undefined) {
|
||||
return prefix + t("setting.webhook.create-dialog.signing-secret-pending-no-changes");
|
||||
// When closing after a successful create, refresh the parent list regardless of how the dialog is dismissed.
|
||||
const handleOpenChange = (next: boolean) => {
|
||||
if (!next && createdSecret !== undefined) {
|
||||
onSuccess?.();
|
||||
}
|
||||
if (state.signingSecret === "") {
|
||||
if (isCreating) {
|
||||
return prefix + t("setting.webhook.create-dialog.signing-secret-pending-no-changes");
|
||||
}
|
||||
return prefix + t("setting.webhook.create-dialog.signing-secret-pending-cleared");
|
||||
}
|
||||
return prefix + t("setting.webhook.create-dialog.signing-secret-pending-generated");
|
||||
onOpenChange(next);
|
||||
};
|
||||
|
||||
const handleSaveBtnClick = async () => {
|
||||
@@ -134,30 +133,32 @@ function CreateWebhookDialog({ open, onOpenChange, webhookName, onSuccess }: Pro
|
||||
try {
|
||||
requestState.setLoading();
|
||||
if (isCreating) {
|
||||
await userServiceClient.createUserWebhook({
|
||||
// The signing secret is generated server-side; reveal it once so the user can copy it without reopening.
|
||||
const created = await userServiceClient.createUserWebhook({
|
||||
parent: currentUser.name,
|
||||
webhook: {
|
||||
displayName: state.displayName,
|
||||
url: state.url,
|
||||
signingSecret: normalizedSigningSecret,
|
||||
},
|
||||
webhook: { displayName: state.displayName, url: state.url },
|
||||
});
|
||||
} else {
|
||||
const updateMaskPaths = ["display_name", "url"];
|
||||
if (state.signingSecret !== undefined) {
|
||||
updateMaskPaths.push("signing_secret");
|
||||
let secret: string | undefined;
|
||||
try {
|
||||
const response = await userServiceClient.getUserWebhookSigningSecret({ name: created.name });
|
||||
secret = response.signingSecret;
|
||||
} catch {
|
||||
// Reveal failed — the secret is still set and can be revealed later from the edit dialog.
|
||||
}
|
||||
await userServiceClient.updateUserWebhook({
|
||||
webhook: {
|
||||
name: webhookName,
|
||||
displayName: state.displayName,
|
||||
url: state.url,
|
||||
...(state.signingSecret !== undefined && { signingSecret: normalizedSigningSecret }),
|
||||
},
|
||||
updateMask: create(FieldMaskSchema, { paths: updateMaskPaths }),
|
||||
});
|
||||
requestState.setFinish();
|
||||
if (secret !== undefined) {
|
||||
setCreatedSecret(secret);
|
||||
return;
|
||||
}
|
||||
onSuccess?.();
|
||||
onOpenChange(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await userServiceClient.updateUserWebhook({
|
||||
webhook: { name: webhookName, displayName: state.displayName, url: state.url },
|
||||
updateMask: create(FieldMaskSchema, { paths: ["display_name", "url"] }),
|
||||
});
|
||||
onSuccess?.();
|
||||
onOpenChange(false);
|
||||
requestState.setFinish();
|
||||
@@ -169,91 +170,108 @@ function CreateWebhookDialog({ open, onOpenChange, webhookName, onSuccess }: Pro
|
||||
}
|
||||
};
|
||||
|
||||
const renderSecretField = (secret: string) => (
|
||||
<div className="flex items-center gap-2">
|
||||
<Input readOnly type="text" value={secret} className="flex-1 font-mono text-xs" />
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => handleCopySecret(secret)}
|
||||
aria-label={t("setting.webhook.create-dialog.copy-secret")}
|
||||
>
|
||||
{secretCopied ? <CheckIcon className="h-4 w-4 text-success" /> : <CopyIcon className="h-4 w-4" />}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderSigningSecret = () => {
|
||||
if (isCreating) {
|
||||
return <span className="text-xs text-muted-foreground">{t("setting.webhook.create-dialog.signing-secret-auto-note")}</span>;
|
||||
}
|
||||
if (revealedSecret !== undefined) {
|
||||
return renderSecretField(revealedSecret);
|
||||
}
|
||||
if (hasExistingSecret) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="flex-1 text-xs text-muted-foreground">{t("setting.webhook.create-dialog.signing-secret-configured")}</span>
|
||||
<Button type="button" variant="outline" size="sm" onClick={handleRevealSecret} disabled={secretState.isLoading}>
|
||||
<EyeIcon className="mr-1 h-3.5 w-3.5" />
|
||||
{t("setting.webhook.create-dialog.reveal-secret")}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="flex-1 text-xs text-muted-foreground">{t("setting.webhook.create-dialog.signing-secret-not-configured")}</span>
|
||||
<Button type="button" variant="outline" size="sm" onClick={handleGenerateSecret} disabled={secretState.isLoading}>
|
||||
{t("setting.webhook.create-dialog.generate-secret")}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<Dialog open={open} onOpenChange={handleOpenChange}>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
{isCreating ? t("setting.webhook.create-dialog.create-webhook") : t("setting.webhook.create-dialog.edit-webhook")}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="flex flex-col gap-4">
|
||||
{createdSecret !== undefined ? (
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="displayName">
|
||||
{t("setting.webhook.create-dialog.title")} <span className="text-destructive">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="displayName"
|
||||
type="text"
|
||||
placeholder={t("setting.webhook.create-dialog.an-easy-to-remember-name")}
|
||||
value={state.displayName}
|
||||
onChange={handleTitleInputChange}
|
||||
/>
|
||||
<Label>{t("setting.webhook.create-dialog.signing-secret")}</Label>
|
||||
<span className="text-xs text-muted-foreground">{t("setting.webhook.create-dialog.signing-secret-created-note")}</span>
|
||||
{renderSecretField(createdSecret)}
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="url">
|
||||
{t("setting.webhook.create-dialog.payload-url")} <span className="text-destructive">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="url"
|
||||
type="text"
|
||||
placeholder={t("setting.webhook.create-dialog.url-example-post-receive")}
|
||||
value={state.url}
|
||||
onChange={handleUrlInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
) : (
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="displayName">
|
||||
{t("setting.webhook.create-dialog.title")} <span className="text-destructive">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="displayName"
|
||||
type="text"
|
||||
placeholder={t("setting.webhook.create-dialog.an-easy-to-remember-name")}
|
||||
value={state.displayName}
|
||||
onChange={handleTitleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="url">
|
||||
{t("setting.webhook.create-dialog.payload-url")} <span className="text-destructive">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="url"
|
||||
type="text"
|
||||
placeholder={t("setting.webhook.create-dialog.url-example-post-receive")}
|
||||
value={state.url}
|
||||
onChange={handleUrlInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label>{t("setting.webhook.create-dialog.signing-secret")}</Label>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{t("setting.webhook.create-dialog.signing-secret-status")}:{" "}
|
||||
{hasExistingSecret
|
||||
? t("setting.webhook.create-dialog.signing-secret-configured")
|
||||
: t("setting.webhook.create-dialog.signing-secret-not-configured")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleGenerateAndCopy}
|
||||
aria-label={t("setting.webhook.create-dialog.generate-and-copy-secret")}
|
||||
>
|
||||
{secretCopied ? (
|
||||
<>
|
||||
<CheckIcon className="mr-1 h-3.5 w-3.5 text-success" />
|
||||
{t("setting.webhook.create-dialog.copied")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<CopyIcon className="mr-1 h-3.5 w-3.5" />
|
||||
{t("setting.webhook.create-dialog.generate-and-copy-secret")}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleClearSecret}
|
||||
disabled={!state.signingSecret && !hasExistingSecret}
|
||||
aria-label={t("setting.webhook.create-dialog.clear-secret")}
|
||||
>
|
||||
<Trash2Icon className="mr-1 h-3.5 w-3.5" />
|
||||
{t("setting.webhook.create-dialog.clear-secret")}
|
||||
</Button>
|
||||
<span className="text-xs text-muted-foreground">{getPendingLabel()}</span>
|
||||
{renderSigningSecret()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<DialogFooter>
|
||||
<Button variant="ghost" disabled={requestState.isLoading} onClick={() => onOpenChange(false)}>
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
<Button disabled={requestState.isLoading} onClick={handleSaveBtnClick}>
|
||||
{isCreating ? t("common.create") : t("common.save")}
|
||||
</Button>
|
||||
{createdSecret !== undefined ? (
|
||||
<Button onClick={() => handleOpenChange(false)}>{t("common.close")}</Button>
|
||||
) : (
|
||||
<>
|
||||
<Button variant="ghost" disabled={requestState.isLoading} onClick={() => onOpenChange(false)}>
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
<Button disabled={requestState.isLoading} onClick={handleSaveBtnClick}>
|
||||
{isCreating ? t("common.create") : t("common.save")}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -759,21 +759,18 @@
|
||||
"webhook": {
|
||||
"create-dialog": {
|
||||
"an-easy-to-remember-name": "An easy-to-remember name",
|
||||
"clear-secret": "Clear",
|
||||
"copied": "Copied",
|
||||
"copy-secret": "Copy signing secret",
|
||||
"create-webhook": "Create webhook",
|
||||
"create-webhook-success": "Webhook `{{name}}` created",
|
||||
"edit-webhook": "Edit webhook",
|
||||
"generate-and-copy-secret": "Generate & Copy",
|
||||
"generate-secret": "Generate",
|
||||
"payload-url": "Payload URL",
|
||||
"reveal-secret": "Reveal",
|
||||
"signing-secret": "Signing Secret",
|
||||
"signing-secret-auto-note": "A signing secret is generated automatically. You can reveal it after creating.",
|
||||
"signing-secret-configured": "Configured",
|
||||
"signing-secret-created-note": "Webhook created. Copy the signing secret now — you can also reveal it later from Edit.",
|
||||
"signing-secret-not-configured": "Not configured",
|
||||
"signing-secret-pending": "Pending",
|
||||
"signing-secret-pending-cleared": "cleared",
|
||||
"signing-secret-pending-generated": "new secret",
|
||||
"signing-secret-pending-no-changes": "no changes",
|
||||
"signing-secret-status": "Status",
|
||||
"title": "Title",
|
||||
"url-example-post-receive": "https://example.com/postreceive"
|
||||
},
|
||||
|
||||
@@ -669,21 +669,18 @@
|
||||
"webhook": {
|
||||
"create-dialog": {
|
||||
"an-easy-to-remember-name": "请输入一个容易记住的标题",
|
||||
"clear-secret": "置空",
|
||||
"copied": "已复制",
|
||||
"copy-secret": "复制签名密钥",
|
||||
"create-webhook": "创建 Webhook",
|
||||
"create-webhook-success": "Webhook `{{name}}` 已创建",
|
||||
"edit-webhook": "编辑 Webhook",
|
||||
"generate-and-copy-secret": "生成并复制",
|
||||
"generate-secret": "生成",
|
||||
"payload-url": "请输入有效的 URL",
|
||||
"reveal-secret": "显示",
|
||||
"signing-secret": "签名密钥",
|
||||
"signing-secret-auto-note": "签名密钥将自动生成,创建后可在此查看。",
|
||||
"signing-secret-configured": "已配置",
|
||||
"signing-secret-created-note": "Webhook 已创建。请立即复制签名密钥,之后也可在编辑中查看。",
|
||||
"signing-secret-not-configured": "未配置",
|
||||
"signing-secret-pending": "待保存",
|
||||
"signing-secret-pending-cleared": "置空",
|
||||
"signing-secret-pending-generated": "新生成",
|
||||
"signing-secret-pending-no-changes": "密钥无改动",
|
||||
"signing-secret-status": "状态",
|
||||
"title": "标题",
|
||||
"url-example-post-receive": "https://example.com/postreceive"
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user