mirror of https://github.com/usememos/memos.git
refactor: rename workspace to instance throughout codebase
Remove work-related terminology by renaming "workspace" to "instance" across the entire application. This change better reflects that Memos is a self-hosted tool suitable for personal and non-work use cases. Breaking Changes: - API endpoints: /api/v1/workspace/* → /api/v1/instance/* - gRPC service: WorkspaceService → InstanceService - Proto types: WorkspaceSetting → InstanceSetting - Frontend translation keys: workspace-section → instance-section Backend Changes: - Renamed proto definitions and regenerated code - Updated all store layer methods and database drivers - Renamed service implementations and API handlers - Updated cache from workspaceSettingCache to instanceSettingCache Frontend Changes: - Renamed service client: workspaceServiceClient → instanceServiceClient - Updated all React components and state management - Refactored stores: workspace.ts → instance.ts - Updated all 32 locale translation files All tests pass and both backend and frontend build successfully. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
d98ee36178
commit
4c1d1c70d1
|
|
@ -122,7 +122,7 @@ The server uses `cmux` (connection multiplexer) to serve both gRPC and HTTP on t
|
||||||
- **HTTP/1.1** → Echo server (REST API via gRPC-Gateway, static files, RSS)
|
- **HTTP/1.1** → Echo server (REST API via gRPC-Gateway, static files, RSS)
|
||||||
|
|
||||||
**API Services** (defined in `proto/api/v1/*.proto`):
|
**API Services** (defined in `proto/api/v1/*.proto`):
|
||||||
- `WorkspaceService` - Workspace settings and profiles
|
- `InstanceService` - Instance settings and profiles
|
||||||
- `AuthService` - Authentication and session management
|
- `AuthService` - Authentication and session management
|
||||||
- `UserService` - User management
|
- `UserService` - User management
|
||||||
- `MemoService` - Core memo CRUD operations
|
- `MemoService` - Core memo CRUD operations
|
||||||
|
|
@ -147,7 +147,7 @@ The `store.Driver` interface (`store/driver.go`) defines all data access methods
|
||||||
- `store/db/postgres/` - PostgreSQL driver
|
- `store/db/postgres/` - PostgreSQL driver
|
||||||
|
|
||||||
**Migrations:**
|
**Migrations:**
|
||||||
Each driver contains its own migration files in subdirectories. Schema version tracking is stored in `workspace_setting` (key: `bb.general.version`). The `store/migrator.go` orchestrates migrations across all drivers.
|
Each driver contains its own migration files in subdirectories. Schema version tracking is stored in `instance_setting` (key: `bb.general.version`). The `store/migrator.go` orchestrates migrations across all drivers.
|
||||||
|
|
||||||
**Key Models:**
|
**Key Models:**
|
||||||
- `Memo` - Core note/memo entity
|
- `Memo` - Core note/memo entity
|
||||||
|
|
@ -157,7 +157,7 @@ Each driver contains its own migration files in subdirectories. Schema version t
|
||||||
- `Activity` - Activity log entries
|
- `Activity` - Activity log entries
|
||||||
- `Inbox` - Inbox items
|
- `Inbox` - Inbox items
|
||||||
- `Reaction` - Emoji reactions
|
- `Reaction` - Emoji reactions
|
||||||
- `WorkspaceSetting` - Workspace-level configuration
|
- `InstanceSetting` - Instance-level configuration
|
||||||
- `UserSetting` - User preferences
|
- `UserSetting` - User preferences
|
||||||
- `IdentityProvider` - OAuth/SSO provider configs
|
- `IdentityProvider` - OAuth/SSO provider configs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,30 +10,30 @@ import "google/protobuf/field_mask.proto";
|
||||||
|
|
||||||
option go_package = "gen/api/v1";
|
option go_package = "gen/api/v1";
|
||||||
|
|
||||||
service WorkspaceService {
|
service InstanceService {
|
||||||
// Gets the workspace profile.
|
// Gets the instance profile.
|
||||||
rpc GetWorkspaceProfile(GetWorkspaceProfileRequest) returns (WorkspaceProfile) {
|
rpc GetInstanceProfile(GetInstanceProfileRequest) returns (InstanceProfile) {
|
||||||
option (google.api.http) = {get: "/api/v1/workspace/profile"};
|
option (google.api.http) = {get: "/api/v1/instance/profile"};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets a workspace setting.
|
// Gets an instance setting.
|
||||||
rpc GetWorkspaceSetting(GetWorkspaceSettingRequest) returns (WorkspaceSetting) {
|
rpc GetInstanceSetting(GetInstanceSettingRequest) returns (InstanceSetting) {
|
||||||
option (google.api.http) = {get: "/api/v1/{name=workspace/settings/*}"};
|
option (google.api.http) = {get: "/api/v1/{name=instance/settings/*}"};
|
||||||
option (google.api.method_signature) = "name";
|
option (google.api.method_signature) = "name";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates a workspace setting.
|
// Updates an instance setting.
|
||||||
rpc UpdateWorkspaceSetting(UpdateWorkspaceSettingRequest) returns (WorkspaceSetting) {
|
rpc UpdateInstanceSetting(UpdateInstanceSettingRequest) returns (InstanceSetting) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
patch: "/api/v1/{setting.name=workspace/settings/*}"
|
patch: "/api/v1/{setting.name=instance/settings/*}"
|
||||||
body: "setting"
|
body: "setting"
|
||||||
};
|
};
|
||||||
option (google.api.method_signature) = "setting,update_mask";
|
option (google.api.method_signature) = "setting,update_mask";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workspace profile message containing basic workspace information.
|
// Instance profile message containing basic instance information.
|
||||||
message WorkspaceProfile {
|
message InstanceProfile {
|
||||||
// The name of instance owner.
|
// The name of instance owner.
|
||||||
// Format: users/{user}
|
// Format: users/{user}
|
||||||
string owner = 1;
|
string owner = 1;
|
||||||
|
|
@ -48,20 +48,20 @@ message WorkspaceProfile {
|
||||||
string instance_url = 6;
|
string instance_url = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request for workspace profile.
|
// Request for instance profile.
|
||||||
message GetWorkspaceProfileRequest {}
|
message GetInstanceProfileRequest {}
|
||||||
|
|
||||||
// A workspace setting resource.
|
// An instance setting resource.
|
||||||
message WorkspaceSetting {
|
message InstanceSetting {
|
||||||
option (google.api.resource) = {
|
option (google.api.resource) = {
|
||||||
type: "memos.api.v1/WorkspaceSetting"
|
type: "memos.api.v1/InstanceSetting"
|
||||||
pattern: "workspace/settings/{setting}"
|
pattern: "instance/settings/{setting}"
|
||||||
singular: "workspaceSetting"
|
singular: "instanceSetting"
|
||||||
plural: "workspaceSettings"
|
plural: "instanceSettings"
|
||||||
};
|
};
|
||||||
|
|
||||||
// The name of the workspace setting.
|
// The name of the instance setting.
|
||||||
// Format: workspace/settings/{setting}
|
// Format: instance/settings/{setting}
|
||||||
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
|
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
|
||||||
|
|
||||||
oneof value {
|
oneof value {
|
||||||
|
|
@ -70,7 +70,7 @@ message WorkspaceSetting {
|
||||||
MemoRelatedSetting memo_related_setting = 4;
|
MemoRelatedSetting memo_related_setting = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enumeration of workspace setting keys.
|
// Enumeration of instance setting keys.
|
||||||
enum Key {
|
enum Key {
|
||||||
KEY_UNSPECIFIED = 0;
|
KEY_UNSPECIFIED = 0;
|
||||||
// GENERAL is the key for general settings.
|
// GENERAL is the key for general settings.
|
||||||
|
|
@ -81,7 +81,7 @@ message WorkspaceSetting {
|
||||||
MEMO_RELATED = 3;
|
MEMO_RELATED = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// General workspace settings configuration.
|
// General instance settings configuration.
|
||||||
message GeneralSetting {
|
message GeneralSetting {
|
||||||
// theme is the name of the selected theme.
|
// theme is the name of the selected theme.
|
||||||
// This references a CSS file in the web/public/themes/ directory.
|
// This references a CSS file in the web/public/themes/ directory.
|
||||||
|
|
@ -106,7 +106,7 @@ message WorkspaceSetting {
|
||||||
// disallow_change_nickname disallows changing nickname.
|
// disallow_change_nickname disallows changing nickname.
|
||||||
bool disallow_change_nickname = 9;
|
bool disallow_change_nickname = 9;
|
||||||
|
|
||||||
// Custom profile configuration for workspace branding.
|
// Custom profile configuration for instance branding.
|
||||||
message CustomProfile {
|
message CustomProfile {
|
||||||
string title = 1;
|
string title = 1;
|
||||||
string description = 2;
|
string description = 2;
|
||||||
|
|
@ -115,7 +115,7 @@ message WorkspaceSetting {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Storage configuration settings for workspace attachments.
|
// Storage configuration settings for instance attachments.
|
||||||
message StorageSetting {
|
message StorageSetting {
|
||||||
// Storage type enumeration for different storage backends.
|
// Storage type enumeration for different storage backends.
|
||||||
enum StorageType {
|
enum StorageType {
|
||||||
|
|
@ -149,7 +149,7 @@ message WorkspaceSetting {
|
||||||
S3Config s3_config = 4;
|
S3Config s3_config = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memo-related workspace settings and policies.
|
// Memo-related instance settings and policies.
|
||||||
message MemoRelatedSetting {
|
message MemoRelatedSetting {
|
||||||
// disallow_public_visibility disallows set memo as public visibility.
|
// disallow_public_visibility disallows set memo as public visibility.
|
||||||
bool disallow_public_visibility = 1;
|
bool disallow_public_visibility = 1;
|
||||||
|
|
@ -172,20 +172,20 @@ message WorkspaceSetting {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request message for GetWorkspaceSetting method.
|
// Request message for GetInstanceSetting method.
|
||||||
message GetWorkspaceSettingRequest {
|
message GetInstanceSettingRequest {
|
||||||
// The resource name of the workspace setting.
|
// The resource name of the instance setting.
|
||||||
// Format: workspace/settings/{setting}
|
// Format: instance/settings/{setting}
|
||||||
string name = 1 [
|
string name = 1 [
|
||||||
(google.api.field_behavior) = REQUIRED,
|
(google.api.field_behavior) = REQUIRED,
|
||||||
(google.api.resource_reference) = {type: "memos.api.v1/WorkspaceSetting"}
|
(google.api.resource_reference) = {type: "memos.api.v1/InstanceSetting"}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request message for UpdateWorkspaceSetting method.
|
// Request message for UpdateInstanceSetting method.
|
||||||
message UpdateWorkspaceSettingRequest {
|
message UpdateInstanceSettingRequest {
|
||||||
// The workspace setting resource which replaces the resource on the server.
|
// The instance setting resource which replaces the resource on the server.
|
||||||
WorkspaceSetting setting = 1 [(google.api.field_behavior) = REQUIRED];
|
InstanceSetting setting = 1 [(google.api.field_behavior) = REQUIRED];
|
||||||
|
|
||||||
// The list of fields to update.
|
// The list of fields to update.
|
||||||
google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL];
|
google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL];
|
||||||
|
|
@ -74,7 +74,7 @@ func (IdentityProvider_Type) EnumDescriptor() ([]byte, []int) {
|
||||||
type IdentityProvider struct {
|
type IdentityProvider struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
// The resource name of the identity provider.
|
// The resource name of the identity provider.
|
||||||
// Format: identityProviders/{idp}
|
// Format: identity-providers/{idp}
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
// Required. The type of the identity provider.
|
// Required. The type of the identity provider.
|
||||||
Type IdentityProvider_Type `protobuf:"varint,2,opt,name=type,proto3,enum=memos.api.v1.IdentityProvider_Type" json:"type,omitempty"`
|
Type IdentityProvider_Type `protobuf:"varint,2,opt,name=type,proto3,enum=memos.api.v1.IdentityProvider_Type" json:"type,omitempty"`
|
||||||
|
|
@ -463,7 +463,7 @@ func (x *ListIdentityProvidersResponse) GetIdentityProviders() []*IdentityProvid
|
||||||
type GetIdentityProviderRequest struct {
|
type GetIdentityProviderRequest struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
// Required. The resource name of the identity provider to get.
|
// Required. The resource name of the identity provider to get.
|
||||||
// Format: identityProviders/{idp}
|
// Format: identity-providers/{idp}
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
|
|
@ -619,7 +619,7 @@ func (x *UpdateIdentityProviderRequest) GetUpdateMask() *fieldmaskpb.FieldMask {
|
||||||
type DeleteIdentityProviderRequest struct {
|
type DeleteIdentityProviderRequest struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
// Required. The resource name of the identity provider to delete.
|
// Required. The resource name of the identity provider to delete.
|
||||||
// Format: identityProviders/{idp}
|
// Format: identity-providers/{idp}
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
|
|
@ -666,7 +666,7 @@ var File_api_v1_idp_service_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
const file_api_v1_idp_service_proto_rawDesc = "" +
|
const file_api_v1_idp_service_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x18api/v1/idp_service.proto\x12\fmemos.api.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\"\x8b\x03\n" +
|
"\x18api/v1/idp_service.proto\x12\fmemos.api.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\"\x8c\x03\n" +
|
||||||
"\x10IdentityProvider\x12\x17\n" +
|
"\x10IdentityProvider\x12\x17\n" +
|
||||||
"\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12<\n" +
|
"\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12<\n" +
|
||||||
"\x04type\x18\x02 \x01(\x0e2#.memos.api.v1.IdentityProvider.TypeB\x03\xe0A\x02R\x04type\x12\x19\n" +
|
"\x04type\x18\x02 \x01(\x0e2#.memos.api.v1.IdentityProvider.TypeB\x03\xe0A\x02R\x04type\x12\x19\n" +
|
||||||
|
|
@ -676,8 +676,8 @@ const file_api_v1_idp_service_proto_rawDesc = "" +
|
||||||
"\x04Type\x12\x14\n" +
|
"\x04Type\x12\x14\n" +
|
||||||
"\x10TYPE_UNSPECIFIED\x10\x00\x12\n" +
|
"\x10TYPE_UNSPECIFIED\x10\x00\x12\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x06OAUTH2\x10\x01:f\xeaAc\n" +
|
"\x06OAUTH2\x10\x01:g\xeaAd\n" +
|
||||||
"\x1dmemos.api.v1/IdentityProvider\x12\x17identityProviders/{idp}\x1a\x04name*\x11identityProviders2\x10identityProvider\"e\n" +
|
"\x1dmemos.api.v1/IdentityProvider\x12\x18identity-providers/{idp}\x1a\x04name*\x11identityProviders2\x10identityProvider\"e\n" +
|
||||||
"\x16IdentityProviderConfig\x12A\n" +
|
"\x16IdentityProviderConfig\x12A\n" +
|
||||||
"\roauth2_config\x18\x01 \x01(\v2\x1a.memos.api.v1.OAuth2ConfigH\x00R\foauth2ConfigB\b\n" +
|
"\roauth2_config\x18\x01 \x01(\v2\x1a.memos.api.v1.OAuth2ConfigH\x00R\foauth2ConfigB\b\n" +
|
||||||
"\x06config\"\x86\x01\n" +
|
"\x06config\"\x86\x01\n" +
|
||||||
|
|
@ -712,13 +712,13 @@ const file_api_v1_idp_service_proto_rawDesc = "" +
|
||||||
"updateMask\"Z\n" +
|
"updateMask\"Z\n" +
|
||||||
"\x1dDeleteIdentityProviderRequest\x129\n" +
|
"\x1dDeleteIdentityProviderRequest\x129\n" +
|
||||||
"\x04name\x18\x01 \x01(\tB%\xe0A\x02\xfaA\x1f\n" +
|
"\x04name\x18\x01 \x01(\tB%\xe0A\x02\xfaA\x1f\n" +
|
||||||
"\x1dmemos.api.v1/IdentityProviderR\x04name2\xe2\x06\n" +
|
"\x1dmemos.api.v1/IdentityProviderR\x04name2\xe7\x06\n" +
|
||||||
"\x17IdentityProviderService\x12\x93\x01\n" +
|
"\x17IdentityProviderService\x12\x94\x01\n" +
|
||||||
"\x15ListIdentityProviders\x12*.memos.api.v1.ListIdentityProvidersRequest\x1a+.memos.api.v1.ListIdentityProvidersResponse\"!\x82\xd3\xe4\x93\x02\x1b\x12\x19/api/v1/identityProviders\x12\x92\x01\n" +
|
"\x15ListIdentityProviders\x12*.memos.api.v1.ListIdentityProvidersRequest\x1a+.memos.api.v1.ListIdentityProvidersResponse\"\"\x82\xd3\xe4\x93\x02\x1c\x12\x1a/api/v1/identity-providers\x12\x93\x01\n" +
|
||||||
"\x13GetIdentityProvider\x12(.memos.api.v1.GetIdentityProviderRequest\x1a\x1e.memos.api.v1.IdentityProvider\"1\xdaA\x04name\x82\xd3\xe4\x93\x02$\x12\"/api/v1/{name=identityProviders/*}\x12\xaf\x01\n" +
|
"\x13GetIdentityProvider\x12(.memos.api.v1.GetIdentityProviderRequest\x1a\x1e.memos.api.v1.IdentityProvider\"2\xdaA\x04name\x82\xd3\xe4\x93\x02%\x12#/api/v1/{name=identity-providers/*}\x12\xb0\x01\n" +
|
||||||
"\x16CreateIdentityProvider\x12+.memos.api.v1.CreateIdentityProviderRequest\x1a\x1e.memos.api.v1.IdentityProvider\"H\xdaA\x11identity_provider\x82\xd3\xe4\x93\x02.:\x11identity_provider\"\x19/api/v1/identityProviders\x12\xd6\x01\n" +
|
"\x16CreateIdentityProvider\x12+.memos.api.v1.CreateIdentityProviderRequest\x1a\x1e.memos.api.v1.IdentityProvider\"I\xdaA\x11identity_provider\x82\xd3\xe4\x93\x02/:\x11identity_provider\"\x1a/api/v1/identity-providers\x12\xd7\x01\n" +
|
||||||
"\x16UpdateIdentityProvider\x12+.memos.api.v1.UpdateIdentityProviderRequest\x1a\x1e.memos.api.v1.IdentityProvider\"o\xdaA\x1didentity_provider,update_mask\x82\xd3\xe4\x93\x02I:\x11identity_provider24/api/v1/{identity_provider.name=identityProviders/*}\x12\x90\x01\n" +
|
"\x16UpdateIdentityProvider\x12+.memos.api.v1.UpdateIdentityProviderRequest\x1a\x1e.memos.api.v1.IdentityProvider\"p\xdaA\x1didentity_provider,update_mask\x82\xd3\xe4\x93\x02J:\x11identity_provider25/api/v1/{identity_provider.name=identity-providers/*}\x12\x91\x01\n" +
|
||||||
"\x16DeleteIdentityProvider\x12+.memos.api.v1.DeleteIdentityProviderRequest\x1a\x16.google.protobuf.Empty\"1\xdaA\x04name\x82\xd3\xe4\x93\x02$*\"/api/v1/{name=identityProviders/*}B\xa7\x01\n" +
|
"\x16DeleteIdentityProvider\x12+.memos.api.v1.DeleteIdentityProviderRequest\x1a\x16.google.protobuf.Empty\"2\xdaA\x04name\x82\xd3\xe4\x93\x02%*#/api/v1/{name=identity-providers/*}B\xa7\x01\n" +
|
||||||
"\x10com.memos.api.v1B\x0fIdpServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3"
|
"\x10com.memos.api.v1B\x0fIdpServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ func RegisterIdentityProviderServiceHandlerServer(ctx context.Context, mux *runt
|
||||||
var stream runtime.ServerTransportStream
|
var stream runtime.ServerTransportStream
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/ListIdentityProviders", runtime.WithHTTPPathPattern("/api/v1/identityProviders"))
|
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/ListIdentityProviders", runtime.WithHTTPPathPattern("/api/v1/identity-providers"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -288,7 +288,7 @@ func RegisterIdentityProviderServiceHandlerServer(ctx context.Context, mux *runt
|
||||||
var stream runtime.ServerTransportStream
|
var stream runtime.ServerTransportStream
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/GetIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{name=identityProviders/*}"))
|
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/GetIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{name=identity-providers/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -308,7 +308,7 @@ func RegisterIdentityProviderServiceHandlerServer(ctx context.Context, mux *runt
|
||||||
var stream runtime.ServerTransportStream
|
var stream runtime.ServerTransportStream
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/CreateIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/identityProviders"))
|
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/CreateIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/identity-providers"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -328,7 +328,7 @@ func RegisterIdentityProviderServiceHandlerServer(ctx context.Context, mux *runt
|
||||||
var stream runtime.ServerTransportStream
|
var stream runtime.ServerTransportStream
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/UpdateIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{identity_provider.name=identityProviders/*}"))
|
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/UpdateIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{identity_provider.name=identity-providers/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -348,7 +348,7 @@ func RegisterIdentityProviderServiceHandlerServer(ctx context.Context, mux *runt
|
||||||
var stream runtime.ServerTransportStream
|
var stream runtime.ServerTransportStream
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/DeleteIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{name=identityProviders/*}"))
|
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/DeleteIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{name=identity-providers/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -406,7 +406,7 @@ func RegisterIdentityProviderServiceHandlerClient(ctx context.Context, mux *runt
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/ListIdentityProviders", runtime.WithHTTPPathPattern("/api/v1/identityProviders"))
|
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/ListIdentityProviders", runtime.WithHTTPPathPattern("/api/v1/identity-providers"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -423,7 +423,7 @@ func RegisterIdentityProviderServiceHandlerClient(ctx context.Context, mux *runt
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/GetIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{name=identityProviders/*}"))
|
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/GetIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{name=identity-providers/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -440,7 +440,7 @@ func RegisterIdentityProviderServiceHandlerClient(ctx context.Context, mux *runt
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/CreateIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/identityProviders"))
|
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/CreateIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/identity-providers"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -457,7 +457,7 @@ func RegisterIdentityProviderServiceHandlerClient(ctx context.Context, mux *runt
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/UpdateIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{identity_provider.name=identityProviders/*}"))
|
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/UpdateIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{identity_provider.name=identity-providers/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -474,7 +474,7 @@ func RegisterIdentityProviderServiceHandlerClient(ctx context.Context, mux *runt
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/DeleteIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{name=identityProviders/*}"))
|
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.IdentityProviderService/DeleteIdentityProvider", runtime.WithHTTPPathPattern("/api/v1/{name=identity-providers/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
|
|
@ -491,11 +491,11 @@ func RegisterIdentityProviderServiceHandlerClient(ctx context.Context, mux *runt
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pattern_IdentityProviderService_ListIdentityProviders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "identityProviders"}, ""))
|
pattern_IdentityProviderService_ListIdentityProviders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "identity-providers"}, ""))
|
||||||
pattern_IdentityProviderService_GetIdentityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "identityProviders", "name"}, ""))
|
pattern_IdentityProviderService_GetIdentityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "identity-providers", "name"}, ""))
|
||||||
pattern_IdentityProviderService_CreateIdentityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "identityProviders"}, ""))
|
pattern_IdentityProviderService_CreateIdentityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "identity-providers"}, ""))
|
||||||
pattern_IdentityProviderService_UpdateIdentityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "identityProviders", "identity_provider.name"}, ""))
|
pattern_IdentityProviderService_UpdateIdentityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "identity-providers", "identity_provider.name"}, ""))
|
||||||
pattern_IdentityProviderService_DeleteIdentityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "identityProviders", "name"}, ""))
|
pattern_IdentityProviderService_DeleteIdentityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "identity-providers", "name"}, ""))
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -1,617 +0,0 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// protoc-gen-go v1.36.10
|
|
||||||
// protoc (unknown)
|
|
||||||
// source: api/v1/inbox_service.proto
|
|
||||||
|
|
||||||
package apiv1
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
|
||||||
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
|
|
||||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
unsafe "unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Verify that this generated code is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
||||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Status enumeration for inbox notifications.
|
|
||||||
type Inbox_Status int32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Unspecified status.
|
|
||||||
Inbox_STATUS_UNSPECIFIED Inbox_Status = 0
|
|
||||||
// The notification is unread.
|
|
||||||
Inbox_UNREAD Inbox_Status = 1
|
|
||||||
// The notification is archived.
|
|
||||||
Inbox_ARCHIVED Inbox_Status = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
// Enum value maps for Inbox_Status.
|
|
||||||
var (
|
|
||||||
Inbox_Status_name = map[int32]string{
|
|
||||||
0: "STATUS_UNSPECIFIED",
|
|
||||||
1: "UNREAD",
|
|
||||||
2: "ARCHIVED",
|
|
||||||
}
|
|
||||||
Inbox_Status_value = map[string]int32{
|
|
||||||
"STATUS_UNSPECIFIED": 0,
|
|
||||||
"UNREAD": 1,
|
|
||||||
"ARCHIVED": 2,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (x Inbox_Status) Enum() *Inbox_Status {
|
|
||||||
p := new(Inbox_Status)
|
|
||||||
*p = x
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x Inbox_Status) String() string {
|
|
||||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (Inbox_Status) Descriptor() protoreflect.EnumDescriptor {
|
|
||||||
return file_api_v1_inbox_service_proto_enumTypes[0].Descriptor()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (Inbox_Status) Type() protoreflect.EnumType {
|
|
||||||
return &file_api_v1_inbox_service_proto_enumTypes[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x Inbox_Status) Number() protoreflect.EnumNumber {
|
|
||||||
return protoreflect.EnumNumber(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use Inbox_Status.Descriptor instead.
|
|
||||||
func (Inbox_Status) EnumDescriptor() ([]byte, []int) {
|
|
||||||
return file_api_v1_inbox_service_proto_rawDescGZIP(), []int{0, 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type enumeration for inbox notifications.
|
|
||||||
type Inbox_Type int32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Unspecified type.
|
|
||||||
Inbox_TYPE_UNSPECIFIED Inbox_Type = 0
|
|
||||||
// Memo comment notification.
|
|
||||||
Inbox_MEMO_COMMENT Inbox_Type = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
// Enum value maps for Inbox_Type.
|
|
||||||
var (
|
|
||||||
Inbox_Type_name = map[int32]string{
|
|
||||||
0: "TYPE_UNSPECIFIED",
|
|
||||||
1: "MEMO_COMMENT",
|
|
||||||
}
|
|
||||||
Inbox_Type_value = map[string]int32{
|
|
||||||
"TYPE_UNSPECIFIED": 0,
|
|
||||||
"MEMO_COMMENT": 1,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (x Inbox_Type) Enum() *Inbox_Type {
|
|
||||||
p := new(Inbox_Type)
|
|
||||||
*p = x
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x Inbox_Type) String() string {
|
|
||||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (Inbox_Type) Descriptor() protoreflect.EnumDescriptor {
|
|
||||||
return file_api_v1_inbox_service_proto_enumTypes[1].Descriptor()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (Inbox_Type) Type() protoreflect.EnumType {
|
|
||||||
return &file_api_v1_inbox_service_proto_enumTypes[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x Inbox_Type) Number() protoreflect.EnumNumber {
|
|
||||||
return protoreflect.EnumNumber(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use Inbox_Type.Descriptor instead.
|
|
||||||
func (Inbox_Type) EnumDescriptor() ([]byte, []int) {
|
|
||||||
return file_api_v1_inbox_service_proto_rawDescGZIP(), []int{0, 1}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Inbox struct {
|
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
|
||||||
// The resource name of the inbox.
|
|
||||||
// Format: inboxes/{inbox}
|
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
|
||||||
// The sender of the inbox notification.
|
|
||||||
// Format: users/{user}
|
|
||||||
Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"`
|
|
||||||
// The receiver of the inbox notification.
|
|
||||||
// Format: users/{user}
|
|
||||||
Receiver string `protobuf:"bytes,3,opt,name=receiver,proto3" json:"receiver,omitempty"`
|
|
||||||
// The status of the inbox notification.
|
|
||||||
Status Inbox_Status `protobuf:"varint,4,opt,name=status,proto3,enum=memos.api.v1.Inbox_Status" json:"status,omitempty"`
|
|
||||||
// Output only. The creation timestamp.
|
|
||||||
CreateTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"`
|
|
||||||
// The type of the inbox notification.
|
|
||||||
Type Inbox_Type `protobuf:"varint,6,opt,name=type,proto3,enum=memos.api.v1.Inbox_Type" json:"type,omitempty"`
|
|
||||||
// Optional. The activity ID associated with this inbox notification.
|
|
||||||
ActivityId *int32 `protobuf:"varint,7,opt,name=activity_id,json=activityId,proto3,oneof" json:"activity_id,omitempty"`
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) Reset() {
|
|
||||||
*x = Inbox{}
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[0]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*Inbox) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *Inbox) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[0]
|
|
||||||
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 Inbox.ProtoReflect.Descriptor instead.
|
|
||||||
func (*Inbox) Descriptor() ([]byte, []int) {
|
|
||||||
return file_api_v1_inbox_service_proto_rawDescGZIP(), []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) GetName() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Name
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) GetSender() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Sender
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) GetReceiver() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Receiver
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) GetStatus() Inbox_Status {
|
|
||||||
if x != nil {
|
|
||||||
return x.Status
|
|
||||||
}
|
|
||||||
return Inbox_STATUS_UNSPECIFIED
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) GetCreateTime() *timestamppb.Timestamp {
|
|
||||||
if x != nil {
|
|
||||||
return x.CreateTime
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) GetType() Inbox_Type {
|
|
||||||
if x != nil {
|
|
||||||
return x.Type
|
|
||||||
}
|
|
||||||
return Inbox_TYPE_UNSPECIFIED
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Inbox) GetActivityId() int32 {
|
|
||||||
if x != nil && x.ActivityId != nil {
|
|
||||||
return *x.ActivityId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListInboxesRequest struct {
|
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
|
||||||
// Required. The parent resource whose inboxes will be listed.
|
|
||||||
// Format: users/{user}
|
|
||||||
Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"`
|
|
||||||
// Optional. The maximum number of inboxes to return.
|
|
||||||
// The service may return fewer than this value.
|
|
||||||
// If unspecified, at most 50 inboxes will be returned.
|
|
||||||
// The maximum value is 1000; values above 1000 will be coerced to 1000.
|
|
||||||
PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
|
|
||||||
// Optional. A page token, received from a previous `ListInboxes` call.
|
|
||||||
// Provide this to retrieve the subsequent page.
|
|
||||||
PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"`
|
|
||||||
// Optional. Filter to apply to the list results.
|
|
||||||
// Example: "status=UNREAD" or "type=MEMO_COMMENT"
|
|
||||||
// Supported operators: =, !=
|
|
||||||
// Supported fields: status, type, sender, create_time
|
|
||||||
Filter string `protobuf:"bytes,4,opt,name=filter,proto3" json:"filter,omitempty"`
|
|
||||||
// Optional. The order to sort results by.
|
|
||||||
// Example: "create_time desc" or "status asc"
|
|
||||||
OrderBy string `protobuf:"bytes,5,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesRequest) Reset() {
|
|
||||||
*x = ListInboxesRequest{}
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[1]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*ListInboxesRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *ListInboxesRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[1]
|
|
||||||
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 ListInboxesRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*ListInboxesRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_api_v1_inbox_service_proto_rawDescGZIP(), []int{1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesRequest) GetParent() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Parent
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesRequest) GetPageSize() int32 {
|
|
||||||
if x != nil {
|
|
||||||
return x.PageSize
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesRequest) GetPageToken() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.PageToken
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesRequest) GetFilter() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Filter
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesRequest) GetOrderBy() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.OrderBy
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListInboxesResponse struct {
|
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
|
||||||
// The list of inboxes.
|
|
||||||
Inboxes []*Inbox `protobuf:"bytes,1,rep,name=inboxes,proto3" json:"inboxes,omitempty"`
|
|
||||||
// A token that can be sent as `page_token` to retrieve the next page.
|
|
||||||
// If this field is omitted, there are no subsequent pages.
|
|
||||||
NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"`
|
|
||||||
// The total count of inboxes (may be approximate).
|
|
||||||
TotalSize int32 `protobuf:"varint,3,opt,name=total_size,json=totalSize,proto3" json:"total_size,omitempty"`
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesResponse) Reset() {
|
|
||||||
*x = ListInboxesResponse{}
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[2]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesResponse) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*ListInboxesResponse) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *ListInboxesResponse) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[2]
|
|
||||||
if x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use ListInboxesResponse.ProtoReflect.Descriptor instead.
|
|
||||||
func (*ListInboxesResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return file_api_v1_inbox_service_proto_rawDescGZIP(), []int{2}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesResponse) GetInboxes() []*Inbox {
|
|
||||||
if x != nil {
|
|
||||||
return x.Inboxes
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesResponse) GetNextPageToken() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.NextPageToken
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListInboxesResponse) GetTotalSize() int32 {
|
|
||||||
if x != nil {
|
|
||||||
return x.TotalSize
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateInboxRequest struct {
|
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
|
||||||
// Required. The inbox to update.
|
|
||||||
Inbox *Inbox `protobuf:"bytes,1,opt,name=inbox,proto3" json:"inbox,omitempty"`
|
|
||||||
// Required. The list of fields to update.
|
|
||||||
UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
|
|
||||||
// Optional. If set to true, allows updating missing fields.
|
|
||||||
AllowMissing bool `protobuf:"varint,3,opt,name=allow_missing,json=allowMissing,proto3" json:"allow_missing,omitempty"`
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateInboxRequest) Reset() {
|
|
||||||
*x = UpdateInboxRequest{}
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[3]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateInboxRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*UpdateInboxRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *UpdateInboxRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[3]
|
|
||||||
if x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use UpdateInboxRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*UpdateInboxRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_api_v1_inbox_service_proto_rawDescGZIP(), []int{3}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateInboxRequest) GetInbox() *Inbox {
|
|
||||||
if x != nil {
|
|
||||||
return x.Inbox
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateInboxRequest) GetUpdateMask() *fieldmaskpb.FieldMask {
|
|
||||||
if x != nil {
|
|
||||||
return x.UpdateMask
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateInboxRequest) GetAllowMissing() bool {
|
|
||||||
if x != nil {
|
|
||||||
return x.AllowMissing
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteInboxRequest struct {
|
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
|
||||||
// Required. The resource name of the inbox to delete.
|
|
||||||
// Format: inboxes/{inbox}
|
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *DeleteInboxRequest) Reset() {
|
|
||||||
*x = DeleteInboxRequest{}
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[4]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *DeleteInboxRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*DeleteInboxRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *DeleteInboxRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_api_v1_inbox_service_proto_msgTypes[4]
|
|
||||||
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 DeleteInboxRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*DeleteInboxRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_api_v1_inbox_service_proto_rawDescGZIP(), []int{4}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *DeleteInboxRequest) GetName() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Name
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_api_v1_inbox_service_proto protoreflect.FileDescriptor
|
|
||||||
|
|
||||||
const file_api_v1_inbox_service_proto_rawDesc = "" +
|
|
||||||
"\n" +
|
|
||||||
"\x1aapi/v1/inbox_service.proto\x12\fmemos.api.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xf3\x03\n" +
|
|
||||||
"\x05Inbox\x12\x17\n" +
|
|
||||||
"\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12\x1b\n" +
|
|
||||||
"\x06sender\x18\x02 \x01(\tB\x03\xe0A\x03R\x06sender\x12\x1f\n" +
|
|
||||||
"\breceiver\x18\x03 \x01(\tB\x03\xe0A\x03R\breceiver\x127\n" +
|
|
||||||
"\x06status\x18\x04 \x01(\x0e2\x1a.memos.api.v1.Inbox.StatusB\x03\xe0A\x01R\x06status\x12@\n" +
|
|
||||||
"\vcreate_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\n" +
|
|
||||||
"createTime\x121\n" +
|
|
||||||
"\x04type\x18\x06 \x01(\x0e2\x18.memos.api.v1.Inbox.TypeB\x03\xe0A\x03R\x04type\x12)\n" +
|
|
||||||
"\vactivity_id\x18\a \x01(\x05B\x03\xe0A\x01H\x00R\n" +
|
|
||||||
"activityId\x88\x01\x01\":\n" +
|
|
||||||
"\x06Status\x12\x16\n" +
|
|
||||||
"\x12STATUS_UNSPECIFIED\x10\x00\x12\n" +
|
|
||||||
"\n" +
|
|
||||||
"\x06UNREAD\x10\x01\x12\f\n" +
|
|
||||||
"\bARCHIVED\x10\x02\".\n" +
|
|
||||||
"\x04Type\x12\x14\n" +
|
|
||||||
"\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n" +
|
|
||||||
"\fMEMO_COMMENT\x10\x01:>\xeaA;\n" +
|
|
||||||
"\x12memos.api.v1/Inbox\x12\x0finboxes/{inbox}\x1a\x04name*\ainboxes2\x05inboxB\x0e\n" +
|
|
||||||
"\f_activity_id\"\xca\x01\n" +
|
|
||||||
"\x12ListInboxesRequest\x121\n" +
|
|
||||||
"\x06parent\x18\x01 \x01(\tB\x19\xe0A\x02\xfaA\x13\n" +
|
|
||||||
"\x11memos.api.v1/UserR\x06parent\x12 \n" +
|
|
||||||
"\tpage_size\x18\x02 \x01(\x05B\x03\xe0A\x01R\bpageSize\x12\"\n" +
|
|
||||||
"\n" +
|
|
||||||
"page_token\x18\x03 \x01(\tB\x03\xe0A\x01R\tpageToken\x12\x1b\n" +
|
|
||||||
"\x06filter\x18\x04 \x01(\tB\x03\xe0A\x01R\x06filter\x12\x1e\n" +
|
|
||||||
"\border_by\x18\x05 \x01(\tB\x03\xe0A\x01R\aorderBy\"\x8b\x01\n" +
|
|
||||||
"\x13ListInboxesResponse\x12-\n" +
|
|
||||||
"\ainboxes\x18\x01 \x03(\v2\x13.memos.api.v1.InboxR\ainboxes\x12&\n" +
|
|
||||||
"\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\x12\x1d\n" +
|
|
||||||
"\n" +
|
|
||||||
"total_size\x18\x03 \x01(\x05R\ttotalSize\"\xb0\x01\n" +
|
|
||||||
"\x12UpdateInboxRequest\x12.\n" +
|
|
||||||
"\x05inbox\x18\x01 \x01(\v2\x13.memos.api.v1.InboxB\x03\xe0A\x02R\x05inbox\x12@\n" +
|
|
||||||
"\vupdate_mask\x18\x02 \x01(\v2\x1a.google.protobuf.FieldMaskB\x03\xe0A\x02R\n" +
|
|
||||||
"updateMask\x12(\n" +
|
|
||||||
"\rallow_missing\x18\x03 \x01(\bB\x03\xe0A\x01R\fallowMissing\"D\n" +
|
|
||||||
"\x12DeleteInboxRequest\x12.\n" +
|
|
||||||
"\x04name\x18\x01 \x01(\tB\x1a\xe0A\x02\xfaA\x14\n" +
|
|
||||||
"\x12memos.api.v1/InboxR\x04name2\x92\x03\n" +
|
|
||||||
"\fInboxService\x12\x85\x01\n" +
|
|
||||||
"\vListInboxes\x12 .memos.api.v1.ListInboxesRequest\x1a!.memos.api.v1.ListInboxesResponse\"1\xdaA\x06parent\x82\xd3\xe4\x93\x02\"\x12 /api/v1/{parent=users/*}/inboxes\x12\x87\x01\n" +
|
|
||||||
"\vUpdateInbox\x12 .memos.api.v1.UpdateInboxRequest\x1a\x13.memos.api.v1.Inbox\"A\xdaA\x11inbox,update_mask\x82\xd3\xe4\x93\x02':\x05inbox2\x1e/api/v1/{inbox.name=inboxes/*}\x12p\n" +
|
|
||||||
"\vDeleteInbox\x12 .memos.api.v1.DeleteInboxRequest\x1a\x16.google.protobuf.Empty\"'\xdaA\x04name\x82\xd3\xe4\x93\x02\x1a*\x18/api/v1/{name=inboxes/*}B\xa9\x01\n" +
|
|
||||||
"\x10com.memos.api.v1B\x11InboxServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3"
|
|
||||||
|
|
||||||
var (
|
|
||||||
file_api_v1_inbox_service_proto_rawDescOnce sync.Once
|
|
||||||
file_api_v1_inbox_service_proto_rawDescData []byte
|
|
||||||
)
|
|
||||||
|
|
||||||
func file_api_v1_inbox_service_proto_rawDescGZIP() []byte {
|
|
||||||
file_api_v1_inbox_service_proto_rawDescOnce.Do(func() {
|
|
||||||
file_api_v1_inbox_service_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_v1_inbox_service_proto_rawDesc), len(file_api_v1_inbox_service_proto_rawDesc)))
|
|
||||||
})
|
|
||||||
return file_api_v1_inbox_service_proto_rawDescData
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_api_v1_inbox_service_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
|
||||||
var file_api_v1_inbox_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
|
||||||
var file_api_v1_inbox_service_proto_goTypes = []any{
|
|
||||||
(Inbox_Status)(0), // 0: memos.api.v1.Inbox.Status
|
|
||||||
(Inbox_Type)(0), // 1: memos.api.v1.Inbox.Type
|
|
||||||
(*Inbox)(nil), // 2: memos.api.v1.Inbox
|
|
||||||
(*ListInboxesRequest)(nil), // 3: memos.api.v1.ListInboxesRequest
|
|
||||||
(*ListInboxesResponse)(nil), // 4: memos.api.v1.ListInboxesResponse
|
|
||||||
(*UpdateInboxRequest)(nil), // 5: memos.api.v1.UpdateInboxRequest
|
|
||||||
(*DeleteInboxRequest)(nil), // 6: memos.api.v1.DeleteInboxRequest
|
|
||||||
(*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp
|
|
||||||
(*fieldmaskpb.FieldMask)(nil), // 8: google.protobuf.FieldMask
|
|
||||||
(*emptypb.Empty)(nil), // 9: google.protobuf.Empty
|
|
||||||
}
|
|
||||||
var file_api_v1_inbox_service_proto_depIdxs = []int32{
|
|
||||||
0, // 0: memos.api.v1.Inbox.status:type_name -> memos.api.v1.Inbox.Status
|
|
||||||
7, // 1: memos.api.v1.Inbox.create_time:type_name -> google.protobuf.Timestamp
|
|
||||||
1, // 2: memos.api.v1.Inbox.type:type_name -> memos.api.v1.Inbox.Type
|
|
||||||
2, // 3: memos.api.v1.ListInboxesResponse.inboxes:type_name -> memos.api.v1.Inbox
|
|
||||||
2, // 4: memos.api.v1.UpdateInboxRequest.inbox:type_name -> memos.api.v1.Inbox
|
|
||||||
8, // 5: memos.api.v1.UpdateInboxRequest.update_mask:type_name -> google.protobuf.FieldMask
|
|
||||||
3, // 6: memos.api.v1.InboxService.ListInboxes:input_type -> memos.api.v1.ListInboxesRequest
|
|
||||||
5, // 7: memos.api.v1.InboxService.UpdateInbox:input_type -> memos.api.v1.UpdateInboxRequest
|
|
||||||
6, // 8: memos.api.v1.InboxService.DeleteInbox:input_type -> memos.api.v1.DeleteInboxRequest
|
|
||||||
4, // 9: memos.api.v1.InboxService.ListInboxes:output_type -> memos.api.v1.ListInboxesResponse
|
|
||||||
2, // 10: memos.api.v1.InboxService.UpdateInbox:output_type -> memos.api.v1.Inbox
|
|
||||||
9, // 11: memos.api.v1.InboxService.DeleteInbox:output_type -> google.protobuf.Empty
|
|
||||||
9, // [9:12] is the sub-list for method output_type
|
|
||||||
6, // [6:9] is the sub-list for method input_type
|
|
||||||
6, // [6:6] is the sub-list for extension type_name
|
|
||||||
6, // [6:6] is the sub-list for extension extendee
|
|
||||||
0, // [0:6] is the sub-list for field type_name
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { file_api_v1_inbox_service_proto_init() }
|
|
||||||
func file_api_v1_inbox_service_proto_init() {
|
|
||||||
if File_api_v1_inbox_service_proto != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
file_api_v1_inbox_service_proto_msgTypes[0].OneofWrappers = []any{}
|
|
||||||
type x struct{}
|
|
||||||
out := protoimpl.TypeBuilder{
|
|
||||||
File: protoimpl.DescBuilder{
|
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_inbox_service_proto_rawDesc), len(file_api_v1_inbox_service_proto_rawDesc)),
|
|
||||||
NumEnums: 2,
|
|
||||||
NumMessages: 5,
|
|
||||||
NumExtensions: 0,
|
|
||||||
NumServices: 1,
|
|
||||||
},
|
|
||||||
GoTypes: file_api_v1_inbox_service_proto_goTypes,
|
|
||||||
DependencyIndexes: file_api_v1_inbox_service_proto_depIdxs,
|
|
||||||
EnumInfos: file_api_v1_inbox_service_proto_enumTypes,
|
|
||||||
MessageInfos: file_api_v1_inbox_service_proto_msgTypes,
|
|
||||||
}.Build()
|
|
||||||
File_api_v1_inbox_service_proto = out.File
|
|
||||||
file_api_v1_inbox_service_proto_goTypes = nil
|
|
||||||
file_api_v1_inbox_service_proto_depIdxs = nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,381 +0,0 @@
|
||||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
|
||||||
// source: api/v1/inbox_service.proto
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package apiv1 is a reverse proxy.
|
|
||||||
|
|
||||||
It translates gRPC into RESTful JSON APIs.
|
|
||||||
*/
|
|
||||||
package apiv1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
|
||||||
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/grpclog"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Suppress "imported and not used" errors
|
|
||||||
var (
|
|
||||||
_ codes.Code
|
|
||||||
_ io.Reader
|
|
||||||
_ status.Status
|
|
||||||
_ = errors.New
|
|
||||||
_ = runtime.String
|
|
||||||
_ = utilities.NewDoubleArray
|
|
||||||
_ = metadata.Join
|
|
||||||
)
|
|
||||||
|
|
||||||
var filter_InboxService_ListInboxes_0 = &utilities.DoubleArray{Encoding: map[string]int{"parent": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
|
||||||
|
|
||||||
func request_InboxService_ListInboxes_0(ctx context.Context, marshaler runtime.Marshaler, client InboxServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
|
||||||
var (
|
|
||||||
protoReq ListInboxesRequest
|
|
||||||
metadata runtime.ServerMetadata
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if req.Body != nil {
|
|
||||||
_, _ = io.Copy(io.Discard, req.Body)
|
|
||||||
}
|
|
||||||
val, ok := pathParams["parent"]
|
|
||||||
if !ok {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "parent")
|
|
||||||
}
|
|
||||||
protoReq.Parent, err = runtime.String(val)
|
|
||||||
if err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err)
|
|
||||||
}
|
|
||||||
if err := req.ParseForm(); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_InboxService_ListInboxes_0); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
msg, err := client.ListInboxes(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
|
||||||
return msg, metadata, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func local_request_InboxService_ListInboxes_0(ctx context.Context, marshaler runtime.Marshaler, server InboxServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
|
||||||
var (
|
|
||||||
protoReq ListInboxesRequest
|
|
||||||
metadata runtime.ServerMetadata
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
val, ok := pathParams["parent"]
|
|
||||||
if !ok {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "parent")
|
|
||||||
}
|
|
||||||
protoReq.Parent, err = runtime.String(val)
|
|
||||||
if err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err)
|
|
||||||
}
|
|
||||||
if err := req.ParseForm(); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_InboxService_ListInboxes_0); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
msg, err := server.ListInboxes(ctx, &protoReq)
|
|
||||||
return msg, metadata, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var filter_InboxService_UpdateInbox_0 = &utilities.DoubleArray{Encoding: map[string]int{"inbox": 0, "name": 1}, Base: []int{1, 2, 1, 0, 0}, Check: []int{0, 1, 2, 3, 2}}
|
|
||||||
|
|
||||||
func request_InboxService_UpdateInbox_0(ctx context.Context, marshaler runtime.Marshaler, client InboxServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
|
||||||
var (
|
|
||||||
protoReq UpdateInboxRequest
|
|
||||||
metadata runtime.ServerMetadata
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
|
||||||
if berr != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
|
||||||
}
|
|
||||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Inbox); err != nil && !errors.Is(err, io.EOF) {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
if req.Body != nil {
|
|
||||||
_, _ = io.Copy(io.Discard, req.Body)
|
|
||||||
}
|
|
||||||
if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 {
|
|
||||||
if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Inbox); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
} else {
|
|
||||||
protoReq.UpdateMask = fieldMask
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val, ok := pathParams["inbox.name"]
|
|
||||||
if !ok {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "inbox.name")
|
|
||||||
}
|
|
||||||
err = runtime.PopulateFieldFromPath(&protoReq, "inbox.name", val)
|
|
||||||
if err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "inbox.name", err)
|
|
||||||
}
|
|
||||||
if err := req.ParseForm(); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_InboxService_UpdateInbox_0); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
msg, err := client.UpdateInbox(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
|
||||||
return msg, metadata, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func local_request_InboxService_UpdateInbox_0(ctx context.Context, marshaler runtime.Marshaler, server InboxServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
|
||||||
var (
|
|
||||||
protoReq UpdateInboxRequest
|
|
||||||
metadata runtime.ServerMetadata
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
|
||||||
if berr != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
|
||||||
}
|
|
||||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Inbox); err != nil && !errors.Is(err, io.EOF) {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 {
|
|
||||||
if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Inbox); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
} else {
|
|
||||||
protoReq.UpdateMask = fieldMask
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val, ok := pathParams["inbox.name"]
|
|
||||||
if !ok {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "inbox.name")
|
|
||||||
}
|
|
||||||
err = runtime.PopulateFieldFromPath(&protoReq, "inbox.name", val)
|
|
||||||
if err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "inbox.name", err)
|
|
||||||
}
|
|
||||||
if err := req.ParseForm(); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_InboxService_UpdateInbox_0); err != nil {
|
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
|
||||||
}
|
|
||||||
msg, err := server.UpdateInbox(ctx, &protoReq)
|
|
||||||
return msg, metadata, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func request_InboxService_DeleteInbox_0(ctx context.Context, marshaler runtime.Marshaler, client InboxServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
|
||||||
var (
|
|
||||||
protoReq DeleteInboxRequest
|
|
||||||
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.DeleteInbox(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
|
||||||
return msg, metadata, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func local_request_InboxService_DeleteInbox_0(ctx context.Context, marshaler runtime.Marshaler, server InboxServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
|
||||||
var (
|
|
||||||
protoReq DeleteInboxRequest
|
|
||||||
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.DeleteInbox(ctx, &protoReq)
|
|
||||||
return msg, metadata, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterInboxServiceHandlerServer registers the http handlers for service InboxService to "mux".
|
|
||||||
// UnaryRPC :call InboxServiceServer directly.
|
|
||||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
|
||||||
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterInboxServiceHandlerFromEndpoint instead.
|
|
||||||
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
|
|
||||||
func RegisterInboxServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server InboxServiceServer) error {
|
|
||||||
mux.Handle(http.MethodGet, pattern_InboxService_ListInboxes_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.InboxService/ListInboxes", runtime.WithHTTPPathPattern("/api/v1/{parent=users/*}/inboxes"))
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, md, err := local_request_InboxService_ListInboxes_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_InboxService_ListInboxes_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
|
||||||
})
|
|
||||||
mux.Handle(http.MethodPatch, pattern_InboxService_UpdateInbox_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.InboxService/UpdateInbox", runtime.WithHTTPPathPattern("/api/v1/{inbox.name=inboxes/*}"))
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, md, err := local_request_InboxService_UpdateInbox_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_InboxService_UpdateInbox_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
|
||||||
})
|
|
||||||
mux.Handle(http.MethodDelete, pattern_InboxService_DeleteInbox_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.InboxService/DeleteInbox", runtime.WithHTTPPathPattern("/api/v1/{name=inboxes/*}"))
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, md, err := local_request_InboxService_DeleteInbox_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_InboxService_DeleteInbox_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterInboxServiceHandlerFromEndpoint is same as RegisterInboxServiceHandler but
|
|
||||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
|
||||||
func RegisterInboxServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
|
||||||
conn, err := grpc.NewClient(endpoint, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
if cerr := conn.Close(); cerr != nil {
|
|
||||||
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
<-ctx.Done()
|
|
||||||
if cerr := conn.Close(); cerr != nil {
|
|
||||||
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}()
|
|
||||||
return RegisterInboxServiceHandler(ctx, mux, conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterInboxServiceHandler registers the http handlers for service InboxService to "mux".
|
|
||||||
// The handlers forward requests to the grpc endpoint over "conn".
|
|
||||||
func RegisterInboxServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
|
||||||
return RegisterInboxServiceHandlerClient(ctx, mux, NewInboxServiceClient(conn))
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterInboxServiceHandlerClient registers the http handlers for service InboxService
|
|
||||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "InboxServiceClient".
|
|
||||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "InboxServiceClient"
|
|
||||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
|
||||||
// "InboxServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares.
|
|
||||||
func RegisterInboxServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client InboxServiceClient) error {
|
|
||||||
mux.Handle(http.MethodGet, pattern_InboxService_ListInboxes_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.InboxService/ListInboxes", runtime.WithHTTPPathPattern("/api/v1/{parent=users/*}/inboxes"))
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, md, err := request_InboxService_ListInboxes_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
forward_InboxService_ListInboxes_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
|
||||||
})
|
|
||||||
mux.Handle(http.MethodPatch, pattern_InboxService_UpdateInbox_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.InboxService/UpdateInbox", runtime.WithHTTPPathPattern("/api/v1/{inbox.name=inboxes/*}"))
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, md, err := request_InboxService_UpdateInbox_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
forward_InboxService_UpdateInbox_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
|
||||||
})
|
|
||||||
mux.Handle(http.MethodDelete, pattern_InboxService_DeleteInbox_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.InboxService/DeleteInbox", runtime.WithHTTPPathPattern("/api/v1/{name=inboxes/*}"))
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, md, err := request_InboxService_DeleteInbox_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
forward_InboxService_DeleteInbox_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
pattern_InboxService_ListInboxes_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", "inboxes"}, ""))
|
|
||||||
pattern_InboxService_UpdateInbox_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "inboxes", "inbox.name"}, ""))
|
|
||||||
pattern_InboxService_DeleteInbox_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "inboxes", "name"}, ""))
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
forward_InboxService_ListInboxes_0 = runtime.ForwardResponseMessage
|
|
||||||
forward_InboxService_UpdateInbox_0 = runtime.ForwardResponseMessage
|
|
||||||
forward_InboxService_DeleteInbox_0 = runtime.ForwardResponseMessage
|
|
||||||
)
|
|
||||||
|
|
@ -1,204 +0,0 @@
|
||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.5.1
|
|
||||||
// - protoc (unknown)
|
|
||||||
// source: api/v1/inbox_service.proto
|
|
||||||
|
|
||||||
package apiv1
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
// Requires gRPC-Go v1.64.0 or later.
|
|
||||||
const _ = grpc.SupportPackageIsVersion9
|
|
||||||
|
|
||||||
const (
|
|
||||||
InboxService_ListInboxes_FullMethodName = "/memos.api.v1.InboxService/ListInboxes"
|
|
||||||
InboxService_UpdateInbox_FullMethodName = "/memos.api.v1.InboxService/UpdateInbox"
|
|
||||||
InboxService_DeleteInbox_FullMethodName = "/memos.api.v1.InboxService/DeleteInbox"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InboxServiceClient is the client API for InboxService service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
|
||||||
type InboxServiceClient interface {
|
|
||||||
// ListInboxes lists inboxes for a user.
|
|
||||||
ListInboxes(ctx context.Context, in *ListInboxesRequest, opts ...grpc.CallOption) (*ListInboxesResponse, error)
|
|
||||||
// UpdateInbox updates an inbox.
|
|
||||||
UpdateInbox(ctx context.Context, in *UpdateInboxRequest, opts ...grpc.CallOption) (*Inbox, error)
|
|
||||||
// DeleteInbox deletes an inbox.
|
|
||||||
DeleteInbox(ctx context.Context, in *DeleteInboxRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type inboxServiceClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewInboxServiceClient(cc grpc.ClientConnInterface) InboxServiceClient {
|
|
||||||
return &inboxServiceClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *inboxServiceClient) ListInboxes(ctx context.Context, in *ListInboxesRequest, opts ...grpc.CallOption) (*ListInboxesResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(ListInboxesResponse)
|
|
||||||
err := c.cc.Invoke(ctx, InboxService_ListInboxes_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *inboxServiceClient) UpdateInbox(ctx context.Context, in *UpdateInboxRequest, opts ...grpc.CallOption) (*Inbox, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(Inbox)
|
|
||||||
err := c.cc.Invoke(ctx, InboxService_UpdateInbox_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *inboxServiceClient) DeleteInbox(ctx context.Context, in *DeleteInboxRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(emptypb.Empty)
|
|
||||||
err := c.cc.Invoke(ctx, InboxService_DeleteInbox_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InboxServiceServer is the server API for InboxService service.
|
|
||||||
// All implementations must embed UnimplementedInboxServiceServer
|
|
||||||
// for forward compatibility.
|
|
||||||
type InboxServiceServer interface {
|
|
||||||
// ListInboxes lists inboxes for a user.
|
|
||||||
ListInboxes(context.Context, *ListInboxesRequest) (*ListInboxesResponse, error)
|
|
||||||
// UpdateInbox updates an inbox.
|
|
||||||
UpdateInbox(context.Context, *UpdateInboxRequest) (*Inbox, error)
|
|
||||||
// DeleteInbox deletes an inbox.
|
|
||||||
DeleteInbox(context.Context, *DeleteInboxRequest) (*emptypb.Empty, error)
|
|
||||||
mustEmbedUnimplementedInboxServiceServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedInboxServiceServer must be embedded to have
|
|
||||||
// forward compatible implementations.
|
|
||||||
//
|
|
||||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
|
||||||
// pointer dereference when methods are called.
|
|
||||||
type UnimplementedInboxServiceServer struct{}
|
|
||||||
|
|
||||||
func (UnimplementedInboxServiceServer) ListInboxes(context.Context, *ListInboxesRequest) (*ListInboxesResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ListInboxes not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedInboxServiceServer) UpdateInbox(context.Context, *UpdateInboxRequest) (*Inbox, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateInbox not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedInboxServiceServer) DeleteInbox(context.Context, *DeleteInboxRequest) (*emptypb.Empty, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteInbox not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedInboxServiceServer) mustEmbedUnimplementedInboxServiceServer() {}
|
|
||||||
func (UnimplementedInboxServiceServer) testEmbeddedByValue() {}
|
|
||||||
|
|
||||||
// UnsafeInboxServiceServer may be embedded to opt out of forward compatibility for this service.
|
|
||||||
// Use of this interface is not recommended, as added methods to InboxServiceServer will
|
|
||||||
// result in compilation errors.
|
|
||||||
type UnsafeInboxServiceServer interface {
|
|
||||||
mustEmbedUnimplementedInboxServiceServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterInboxServiceServer(s grpc.ServiceRegistrar, srv InboxServiceServer) {
|
|
||||||
// If the following call pancis, it indicates UnimplementedInboxServiceServer was
|
|
||||||
// embedded by pointer and is nil. This will cause panics if an
|
|
||||||
// unimplemented method is ever invoked, so we test this at initialization
|
|
||||||
// time to prevent it from happening at runtime later due to I/O.
|
|
||||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
|
||||||
t.testEmbeddedByValue()
|
|
||||||
}
|
|
||||||
s.RegisterService(&InboxService_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _InboxService_ListInboxes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(ListInboxesRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(InboxServiceServer).ListInboxes(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: InboxService_ListInboxes_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(InboxServiceServer).ListInboxes(ctx, req.(*ListInboxesRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _InboxService_UpdateInbox_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(UpdateInboxRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(InboxServiceServer).UpdateInbox(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: InboxService_UpdateInbox_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(InboxServiceServer).UpdateInbox(ctx, req.(*UpdateInboxRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _InboxService_DeleteInbox_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(DeleteInboxRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(InboxServiceServer).DeleteInbox(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: InboxService_DeleteInbox_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(InboxServiceServer).DeleteInbox(ctx, req.(*DeleteInboxRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InboxService_ServiceDesc is the grpc.ServiceDesc for InboxService service.
|
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
|
||||||
// and not to be introspected or modified (even as a copy)
|
|
||||||
var InboxService_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "memos.api.v1.InboxService",
|
|
||||||
HandlerType: (*InboxServiceServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "ListInboxes",
|
|
||||||
Handler: _InboxService_ListInboxes_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "UpdateInbox",
|
|
||||||
Handler: _InboxService_UpdateInbox_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "DeleteInbox",
|
|
||||||
Handler: _InboxService_DeleteInbox_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "api/v1/inbox_service.proto",
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
||||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||||
// source: api/v1/workspace_service.proto
|
// source: api/v1/instance_service.proto
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Package apiv1 is a reverse proxy.
|
Package apiv1 is a reverse proxy.
|
||||||
|
|
@ -35,30 +35,30 @@ var (
|
||||||
_ = metadata.Join
|
_ = metadata.Join
|
||||||
)
|
)
|
||||||
|
|
||||||
func request_WorkspaceService_GetWorkspaceProfile_0(ctx context.Context, marshaler runtime.Marshaler, client WorkspaceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_InstanceService_GetInstanceProfile_0(ctx context.Context, marshaler runtime.Marshaler, client InstanceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var (
|
var (
|
||||||
protoReq GetWorkspaceProfileRequest
|
protoReq GetInstanceProfileRequest
|
||||||
metadata runtime.ServerMetadata
|
metadata runtime.ServerMetadata
|
||||||
)
|
)
|
||||||
if req.Body != nil {
|
if req.Body != nil {
|
||||||
_, _ = io.Copy(io.Discard, req.Body)
|
_, _ = io.Copy(io.Discard, req.Body)
|
||||||
}
|
}
|
||||||
msg, err := client.GetWorkspaceProfile(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
msg, err := client.GetInstanceProfile(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
return msg, metadata, err
|
return msg, metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func local_request_WorkspaceService_GetWorkspaceProfile_0(ctx context.Context, marshaler runtime.Marshaler, server WorkspaceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func local_request_InstanceService_GetInstanceProfile_0(ctx context.Context, marshaler runtime.Marshaler, server InstanceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var (
|
var (
|
||||||
protoReq GetWorkspaceProfileRequest
|
protoReq GetInstanceProfileRequest
|
||||||
metadata runtime.ServerMetadata
|
metadata runtime.ServerMetadata
|
||||||
)
|
)
|
||||||
msg, err := server.GetWorkspaceProfile(ctx, &protoReq)
|
msg, err := server.GetInstanceProfile(ctx, &protoReq)
|
||||||
return msg, metadata, err
|
return msg, metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func request_WorkspaceService_GetWorkspaceSetting_0(ctx context.Context, marshaler runtime.Marshaler, client WorkspaceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_InstanceService_GetInstanceSetting_0(ctx context.Context, marshaler runtime.Marshaler, client InstanceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var (
|
var (
|
||||||
protoReq GetWorkspaceSettingRequest
|
protoReq GetInstanceSettingRequest
|
||||||
metadata runtime.ServerMetadata
|
metadata runtime.ServerMetadata
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
@ -73,13 +73,13 @@ func request_WorkspaceService_GetWorkspaceSetting_0(ctx context.Context, marshal
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||||
}
|
}
|
||||||
msg, err := client.GetWorkspaceSetting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
msg, err := client.GetInstanceSetting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
return msg, metadata, err
|
return msg, metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func local_request_WorkspaceService_GetWorkspaceSetting_0(ctx context.Context, marshaler runtime.Marshaler, server WorkspaceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func local_request_InstanceService_GetInstanceSetting_0(ctx context.Context, marshaler runtime.Marshaler, server InstanceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var (
|
var (
|
||||||
protoReq GetWorkspaceSettingRequest
|
protoReq GetInstanceSettingRequest
|
||||||
metadata runtime.ServerMetadata
|
metadata runtime.ServerMetadata
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
@ -91,15 +91,15 @@ func local_request_WorkspaceService_GetWorkspaceSetting_0(ctx context.Context, m
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||||
}
|
}
|
||||||
msg, err := server.GetWorkspaceSetting(ctx, &protoReq)
|
msg, err := server.GetInstanceSetting(ctx, &protoReq)
|
||||||
return msg, metadata, err
|
return msg, metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var filter_WorkspaceService_UpdateWorkspaceSetting_0 = &utilities.DoubleArray{Encoding: map[string]int{"setting": 0, "name": 1}, Base: []int{1, 2, 1, 0, 0}, Check: []int{0, 1, 2, 3, 2}}
|
var filter_InstanceService_UpdateInstanceSetting_0 = &utilities.DoubleArray{Encoding: map[string]int{"setting": 0, "name": 1}, Base: []int{1, 2, 1, 0, 0}, Check: []int{0, 1, 2, 3, 2}}
|
||||||
|
|
||||||
func request_WorkspaceService_UpdateWorkspaceSetting_0(ctx context.Context, marshaler runtime.Marshaler, client WorkspaceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_InstanceService_UpdateInstanceSetting_0(ctx context.Context, marshaler runtime.Marshaler, client InstanceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var (
|
var (
|
||||||
protoReq UpdateWorkspaceSettingRequest
|
protoReq UpdateInstanceSettingRequest
|
||||||
metadata runtime.ServerMetadata
|
metadata runtime.ServerMetadata
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
@ -131,16 +131,16 @@ func request_WorkspaceService_UpdateWorkspaceSetting_0(ctx context.Context, mars
|
||||||
if err := req.ParseForm(); err != nil {
|
if err := req.ParseForm(); err != nil {
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
}
|
}
|
||||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WorkspaceService_UpdateWorkspaceSetting_0); err != nil {
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_InstanceService_UpdateInstanceSetting_0); err != nil {
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
}
|
}
|
||||||
msg, err := client.UpdateWorkspaceSetting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
msg, err := client.UpdateInstanceSetting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
return msg, metadata, err
|
return msg, metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func local_request_WorkspaceService_UpdateWorkspaceSetting_0(ctx context.Context, marshaler runtime.Marshaler, server WorkspaceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func local_request_InstanceService_UpdateInstanceSetting_0(ctx context.Context, marshaler runtime.Marshaler, server InstanceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var (
|
var (
|
||||||
protoReq UpdateWorkspaceSettingRequest
|
protoReq UpdateInstanceSettingRequest
|
||||||
metadata runtime.ServerMetadata
|
metadata runtime.ServerMetadata
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
@ -169,86 +169,86 @@ func local_request_WorkspaceService_UpdateWorkspaceSetting_0(ctx context.Context
|
||||||
if err := req.ParseForm(); err != nil {
|
if err := req.ParseForm(); err != nil {
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
}
|
}
|
||||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WorkspaceService_UpdateWorkspaceSetting_0); err != nil {
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_InstanceService_UpdateInstanceSetting_0); err != nil {
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
}
|
}
|
||||||
msg, err := server.UpdateWorkspaceSetting(ctx, &protoReq)
|
msg, err := server.UpdateInstanceSetting(ctx, &protoReq)
|
||||||
return msg, metadata, err
|
return msg, metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterWorkspaceServiceHandlerServer registers the http handlers for service WorkspaceService to "mux".
|
// RegisterInstanceServiceHandlerServer registers the http handlers for service InstanceService to "mux".
|
||||||
// UnaryRPC :call WorkspaceServiceServer directly.
|
// UnaryRPC :call InstanceServiceServer directly.
|
||||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||||
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterWorkspaceServiceHandlerFromEndpoint instead.
|
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterInstanceServiceHandlerFromEndpoint instead.
|
||||||
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
|
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
|
||||||
func RegisterWorkspaceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server WorkspaceServiceServer) error {
|
func RegisterInstanceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server InstanceServiceServer) error {
|
||||||
mux.Handle(http.MethodGet, pattern_WorkspaceService_GetWorkspaceProfile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle(http.MethodGet, pattern_InstanceService_GetInstanceProfile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
var stream runtime.ServerTransportStream
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.WorkspaceService/GetWorkspaceProfile", runtime.WithHTTPPathPattern("/api/v1/workspace/profile"))
|
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.InstanceService/GetInstanceProfile", runtime.WithHTTPPathPattern("/api/v1/instance/profile"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_WorkspaceService_GetWorkspaceProfile_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
resp, md, err := local_request_InstanceService_GetInstanceProfile_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
forward_WorkspaceService_GetWorkspaceProfile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
forward_InstanceService_GetInstanceProfile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
})
|
})
|
||||||
mux.Handle(http.MethodGet, pattern_WorkspaceService_GetWorkspaceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle(http.MethodGet, pattern_InstanceService_GetInstanceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
var stream runtime.ServerTransportStream
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.WorkspaceService/GetWorkspaceSetting", runtime.WithHTTPPathPattern("/api/v1/{name=workspace/settings/*}"))
|
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.InstanceService/GetInstanceSetting", runtime.WithHTTPPathPattern("/api/v1/{name=instance/settings/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_WorkspaceService_GetWorkspaceSetting_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
resp, md, err := local_request_InstanceService_GetInstanceSetting_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
forward_WorkspaceService_GetWorkspaceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
forward_InstanceService_GetInstanceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
})
|
})
|
||||||
mux.Handle(http.MethodPatch, pattern_WorkspaceService_UpdateWorkspaceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle(http.MethodPatch, pattern_InstanceService_UpdateInstanceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
var stream runtime.ServerTransportStream
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.WorkspaceService/UpdateWorkspaceSetting", runtime.WithHTTPPathPattern("/api/v1/{setting.name=workspace/settings/*}"))
|
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.InstanceService/UpdateInstanceSetting", runtime.WithHTTPPathPattern("/api/v1/{setting.name=instance/settings/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_WorkspaceService_UpdateWorkspaceSetting_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
resp, md, err := local_request_InstanceService_UpdateInstanceSetting_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
forward_WorkspaceService_UpdateWorkspaceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
forward_InstanceService_UpdateInstanceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterWorkspaceServiceHandlerFromEndpoint is same as RegisterWorkspaceServiceHandler but
|
// RegisterInstanceServiceHandlerFromEndpoint is same as RegisterInstanceServiceHandler but
|
||||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||||
func RegisterWorkspaceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
func RegisterInstanceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||||
conn, err := grpc.NewClient(endpoint, opts...)
|
conn, err := grpc.NewClient(endpoint, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -267,83 +267,83 @@ func RegisterWorkspaceServiceHandlerFromEndpoint(ctx context.Context, mux *runti
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}()
|
}()
|
||||||
return RegisterWorkspaceServiceHandler(ctx, mux, conn)
|
return RegisterInstanceServiceHandler(ctx, mux, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterWorkspaceServiceHandler registers the http handlers for service WorkspaceService to "mux".
|
// RegisterInstanceServiceHandler registers the http handlers for service InstanceService to "mux".
|
||||||
// The handlers forward requests to the grpc endpoint over "conn".
|
// The handlers forward requests to the grpc endpoint over "conn".
|
||||||
func RegisterWorkspaceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
func RegisterInstanceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||||
return RegisterWorkspaceServiceHandlerClient(ctx, mux, NewWorkspaceServiceClient(conn))
|
return RegisterInstanceServiceHandlerClient(ctx, mux, NewInstanceServiceClient(conn))
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterWorkspaceServiceHandlerClient registers the http handlers for service WorkspaceService
|
// RegisterInstanceServiceHandlerClient registers the http handlers for service InstanceService
|
||||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "WorkspaceServiceClient".
|
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "InstanceServiceClient".
|
||||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "WorkspaceServiceClient"
|
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "InstanceServiceClient"
|
||||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||||
// "WorkspaceServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares.
|
// "InstanceServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares.
|
||||||
func RegisterWorkspaceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client WorkspaceServiceClient) error {
|
func RegisterInstanceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client InstanceServiceClient) error {
|
||||||
mux.Handle(http.MethodGet, pattern_WorkspaceService_GetWorkspaceProfile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle(http.MethodGet, pattern_InstanceService_GetInstanceProfile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.WorkspaceService/GetWorkspaceProfile", runtime.WithHTTPPathPattern("/api/v1/workspace/profile"))
|
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.InstanceService/GetInstanceProfile", runtime.WithHTTPPathPattern("/api/v1/instance/profile"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := request_WorkspaceService_GetWorkspaceProfile_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
resp, md, err := request_InstanceService_GetInstanceProfile_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
forward_WorkspaceService_GetWorkspaceProfile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
forward_InstanceService_GetInstanceProfile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
})
|
})
|
||||||
mux.Handle(http.MethodGet, pattern_WorkspaceService_GetWorkspaceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle(http.MethodGet, pattern_InstanceService_GetInstanceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.WorkspaceService/GetWorkspaceSetting", runtime.WithHTTPPathPattern("/api/v1/{name=workspace/settings/*}"))
|
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.InstanceService/GetInstanceSetting", runtime.WithHTTPPathPattern("/api/v1/{name=instance/settings/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := request_WorkspaceService_GetWorkspaceSetting_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
resp, md, err := request_InstanceService_GetInstanceSetting_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
forward_WorkspaceService_GetWorkspaceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
forward_InstanceService_GetInstanceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
})
|
})
|
||||||
mux.Handle(http.MethodPatch, pattern_WorkspaceService_UpdateWorkspaceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle(http.MethodPatch, pattern_InstanceService_UpdateInstanceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.WorkspaceService/UpdateWorkspaceSetting", runtime.WithHTTPPathPattern("/api/v1/{setting.name=workspace/settings/*}"))
|
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.InstanceService/UpdateInstanceSetting", runtime.WithHTTPPathPattern("/api/v1/{setting.name=instance/settings/*}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := request_WorkspaceService_UpdateWorkspaceSetting_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
resp, md, err := request_InstanceService_UpdateInstanceSetting_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
forward_WorkspaceService_UpdateWorkspaceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
forward_InstanceService_UpdateInstanceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pattern_WorkspaceService_GetWorkspaceProfile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "workspace", "profile"}, ""))
|
pattern_InstanceService_GetInstanceProfile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "instance", "profile"}, ""))
|
||||||
pattern_WorkspaceService_GetWorkspaceSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 3, 5, 4}, []string{"api", "v1", "workspace", "settings", "name"}, ""))
|
pattern_InstanceService_GetInstanceSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 3, 5, 4}, []string{"api", "v1", "instance", "settings", "name"}, ""))
|
||||||
pattern_WorkspaceService_UpdateWorkspaceSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 3, 5, 4}, []string{"api", "v1", "workspace", "settings", "setting.name"}, ""))
|
pattern_InstanceService_UpdateInstanceSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 3, 5, 4}, []string{"api", "v1", "instance", "settings", "setting.name"}, ""))
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
forward_WorkspaceService_GetWorkspaceProfile_0 = runtime.ForwardResponseMessage
|
forward_InstanceService_GetInstanceProfile_0 = runtime.ForwardResponseMessage
|
||||||
forward_WorkspaceService_GetWorkspaceSetting_0 = runtime.ForwardResponseMessage
|
forward_InstanceService_GetInstanceSetting_0 = runtime.ForwardResponseMessage
|
||||||
forward_WorkspaceService_UpdateWorkspaceSetting_0 = runtime.ForwardResponseMessage
|
forward_InstanceService_UpdateInstanceSetting_0 = runtime.ForwardResponseMessage
|
||||||
)
|
)
|
||||||
|
|
@ -0,0 +1,203 @@
|
||||||
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// - protoc-gen-go-grpc v1.5.1
|
||||||
|
// - protoc (unknown)
|
||||||
|
// source: api/v1/instance_service.proto
|
||||||
|
|
||||||
|
package apiv1
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
grpc "google.golang.org/grpc"
|
||||||
|
codes "google.golang.org/grpc/codes"
|
||||||
|
status "google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the grpc package it is being compiled against.
|
||||||
|
// Requires gRPC-Go v1.64.0 or later.
|
||||||
|
const _ = grpc.SupportPackageIsVersion9
|
||||||
|
|
||||||
|
const (
|
||||||
|
InstanceService_GetInstanceProfile_FullMethodName = "/memos.api.v1.InstanceService/GetInstanceProfile"
|
||||||
|
InstanceService_GetInstanceSetting_FullMethodName = "/memos.api.v1.InstanceService/GetInstanceSetting"
|
||||||
|
InstanceService_UpdateInstanceSetting_FullMethodName = "/memos.api.v1.InstanceService/UpdateInstanceSetting"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InstanceServiceClient is the client API for InstanceService service.
|
||||||
|
//
|
||||||
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||||
|
type InstanceServiceClient interface {
|
||||||
|
// Gets the instance profile.
|
||||||
|
GetInstanceProfile(ctx context.Context, in *GetInstanceProfileRequest, opts ...grpc.CallOption) (*InstanceProfile, error)
|
||||||
|
// Gets an instance setting.
|
||||||
|
GetInstanceSetting(ctx context.Context, in *GetInstanceSettingRequest, opts ...grpc.CallOption) (*InstanceSetting, error)
|
||||||
|
// Updates an instance setting.
|
||||||
|
UpdateInstanceSetting(ctx context.Context, in *UpdateInstanceSettingRequest, opts ...grpc.CallOption) (*InstanceSetting, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type instanceServiceClient struct {
|
||||||
|
cc grpc.ClientConnInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInstanceServiceClient(cc grpc.ClientConnInterface) InstanceServiceClient {
|
||||||
|
return &instanceServiceClient{cc}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *instanceServiceClient) GetInstanceProfile(ctx context.Context, in *GetInstanceProfileRequest, opts ...grpc.CallOption) (*InstanceProfile, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(InstanceProfile)
|
||||||
|
err := c.cc.Invoke(ctx, InstanceService_GetInstanceProfile_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *instanceServiceClient) GetInstanceSetting(ctx context.Context, in *GetInstanceSettingRequest, opts ...grpc.CallOption) (*InstanceSetting, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(InstanceSetting)
|
||||||
|
err := c.cc.Invoke(ctx, InstanceService_GetInstanceSetting_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *instanceServiceClient) UpdateInstanceSetting(ctx context.Context, in *UpdateInstanceSettingRequest, opts ...grpc.CallOption) (*InstanceSetting, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(InstanceSetting)
|
||||||
|
err := c.cc.Invoke(ctx, InstanceService_UpdateInstanceSetting_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstanceServiceServer is the server API for InstanceService service.
|
||||||
|
// All implementations must embed UnimplementedInstanceServiceServer
|
||||||
|
// for forward compatibility.
|
||||||
|
type InstanceServiceServer interface {
|
||||||
|
// Gets the instance profile.
|
||||||
|
GetInstanceProfile(context.Context, *GetInstanceProfileRequest) (*InstanceProfile, error)
|
||||||
|
// Gets an instance setting.
|
||||||
|
GetInstanceSetting(context.Context, *GetInstanceSettingRequest) (*InstanceSetting, error)
|
||||||
|
// Updates an instance setting.
|
||||||
|
UpdateInstanceSetting(context.Context, *UpdateInstanceSettingRequest) (*InstanceSetting, error)
|
||||||
|
mustEmbedUnimplementedInstanceServiceServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnimplementedInstanceServiceServer must be embedded to have
|
||||||
|
// forward compatible implementations.
|
||||||
|
//
|
||||||
|
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||||
|
// pointer dereference when methods are called.
|
||||||
|
type UnimplementedInstanceServiceServer struct{}
|
||||||
|
|
||||||
|
func (UnimplementedInstanceServiceServer) GetInstanceProfile(context.Context, *GetInstanceProfileRequest) (*InstanceProfile, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetInstanceProfile not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedInstanceServiceServer) GetInstanceSetting(context.Context, *GetInstanceSettingRequest) (*InstanceSetting, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetInstanceSetting not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedInstanceServiceServer) UpdateInstanceSetting(context.Context, *UpdateInstanceSettingRequest) (*InstanceSetting, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method UpdateInstanceSetting not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedInstanceServiceServer) mustEmbedUnimplementedInstanceServiceServer() {}
|
||||||
|
func (UnimplementedInstanceServiceServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
|
// UnsafeInstanceServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||||
|
// Use of this interface is not recommended, as added methods to InstanceServiceServer will
|
||||||
|
// result in compilation errors.
|
||||||
|
type UnsafeInstanceServiceServer interface {
|
||||||
|
mustEmbedUnimplementedInstanceServiceServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterInstanceServiceServer(s grpc.ServiceRegistrar, srv InstanceServiceServer) {
|
||||||
|
// If the following call pancis, it indicates UnimplementedInstanceServiceServer was
|
||||||
|
// embedded by pointer and is nil. This will cause panics if an
|
||||||
|
// unimplemented method is ever invoked, so we test this at initialization
|
||||||
|
// time to prevent it from happening at runtime later due to I/O.
|
||||||
|
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||||
|
t.testEmbeddedByValue()
|
||||||
|
}
|
||||||
|
s.RegisterService(&InstanceService_ServiceDesc, srv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _InstanceService_GetInstanceProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(GetInstanceProfileRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(InstanceServiceServer).GetInstanceProfile(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: InstanceService_GetInstanceProfile_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(InstanceServiceServer).GetInstanceProfile(ctx, req.(*GetInstanceProfileRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _InstanceService_GetInstanceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(GetInstanceSettingRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(InstanceServiceServer).GetInstanceSetting(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: InstanceService_GetInstanceSetting_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(InstanceServiceServer).GetInstanceSetting(ctx, req.(*GetInstanceSettingRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _InstanceService_UpdateInstanceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(UpdateInstanceSettingRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(InstanceServiceServer).UpdateInstanceSetting(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: InstanceService_UpdateInstanceSetting_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(InstanceServiceServer).UpdateInstanceSetting(ctx, req.(*UpdateInstanceSettingRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstanceService_ServiceDesc is the grpc.ServiceDesc for InstanceService service.
|
||||||
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
|
// and not to be introspected or modified (even as a copy)
|
||||||
|
var InstanceService_ServiceDesc = grpc.ServiceDesc{
|
||||||
|
ServiceName: "memos.api.v1.InstanceService",
|
||||||
|
HandlerType: (*InstanceServiceServer)(nil),
|
||||||
|
Methods: []grpc.MethodDesc{
|
||||||
|
{
|
||||||
|
MethodName: "GetInstanceProfile",
|
||||||
|
Handler: _InstanceService_GetInstanceProfile_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetInstanceSetting",
|
||||||
|
Handler: _InstanceService_GetInstanceSetting_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "UpdateInstanceSetting",
|
||||||
|
Handler: _InstanceService_UpdateInstanceSetting_Handler,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Streams: []grpc.StreamDesc{},
|
||||||
|
Metadata: "api/v1/instance_service.proto",
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,203 +0,0 @@
|
||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.5.1
|
|
||||||
// - protoc (unknown)
|
|
||||||
// source: api/v1/workspace_service.proto
|
|
||||||
|
|
||||||
package apiv1
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
// Requires gRPC-Go v1.64.0 or later.
|
|
||||||
const _ = grpc.SupportPackageIsVersion9
|
|
||||||
|
|
||||||
const (
|
|
||||||
WorkspaceService_GetWorkspaceProfile_FullMethodName = "/memos.api.v1.WorkspaceService/GetWorkspaceProfile"
|
|
||||||
WorkspaceService_GetWorkspaceSetting_FullMethodName = "/memos.api.v1.WorkspaceService/GetWorkspaceSetting"
|
|
||||||
WorkspaceService_UpdateWorkspaceSetting_FullMethodName = "/memos.api.v1.WorkspaceService/UpdateWorkspaceSetting"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WorkspaceServiceClient is the client API for WorkspaceService service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
|
||||||
type WorkspaceServiceClient interface {
|
|
||||||
// Gets the workspace profile.
|
|
||||||
GetWorkspaceProfile(ctx context.Context, in *GetWorkspaceProfileRequest, opts ...grpc.CallOption) (*WorkspaceProfile, error)
|
|
||||||
// Gets a workspace setting.
|
|
||||||
GetWorkspaceSetting(ctx context.Context, in *GetWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error)
|
|
||||||
// Updates a workspace setting.
|
|
||||||
UpdateWorkspaceSetting(ctx context.Context, in *UpdateWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type workspaceServiceClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWorkspaceServiceClient(cc grpc.ClientConnInterface) WorkspaceServiceClient {
|
|
||||||
return &workspaceServiceClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *workspaceServiceClient) GetWorkspaceProfile(ctx context.Context, in *GetWorkspaceProfileRequest, opts ...grpc.CallOption) (*WorkspaceProfile, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(WorkspaceProfile)
|
|
||||||
err := c.cc.Invoke(ctx, WorkspaceService_GetWorkspaceProfile_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *workspaceServiceClient) GetWorkspaceSetting(ctx context.Context, in *GetWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(WorkspaceSetting)
|
|
||||||
err := c.cc.Invoke(ctx, WorkspaceService_GetWorkspaceSetting_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *workspaceServiceClient) UpdateWorkspaceSetting(ctx context.Context, in *UpdateWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(WorkspaceSetting)
|
|
||||||
err := c.cc.Invoke(ctx, WorkspaceService_UpdateWorkspaceSetting_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WorkspaceServiceServer is the server API for WorkspaceService service.
|
|
||||||
// All implementations must embed UnimplementedWorkspaceServiceServer
|
|
||||||
// for forward compatibility.
|
|
||||||
type WorkspaceServiceServer interface {
|
|
||||||
// Gets the workspace profile.
|
|
||||||
GetWorkspaceProfile(context.Context, *GetWorkspaceProfileRequest) (*WorkspaceProfile, error)
|
|
||||||
// Gets a workspace setting.
|
|
||||||
GetWorkspaceSetting(context.Context, *GetWorkspaceSettingRequest) (*WorkspaceSetting, error)
|
|
||||||
// Updates a workspace setting.
|
|
||||||
UpdateWorkspaceSetting(context.Context, *UpdateWorkspaceSettingRequest) (*WorkspaceSetting, error)
|
|
||||||
mustEmbedUnimplementedWorkspaceServiceServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedWorkspaceServiceServer must be embedded to have
|
|
||||||
// forward compatible implementations.
|
|
||||||
//
|
|
||||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
|
||||||
// pointer dereference when methods are called.
|
|
||||||
type UnimplementedWorkspaceServiceServer struct{}
|
|
||||||
|
|
||||||
func (UnimplementedWorkspaceServiceServer) GetWorkspaceProfile(context.Context, *GetWorkspaceProfileRequest) (*WorkspaceProfile, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetWorkspaceProfile not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedWorkspaceServiceServer) GetWorkspaceSetting(context.Context, *GetWorkspaceSettingRequest) (*WorkspaceSetting, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetWorkspaceSetting not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedWorkspaceServiceServer) UpdateWorkspaceSetting(context.Context, *UpdateWorkspaceSettingRequest) (*WorkspaceSetting, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateWorkspaceSetting not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedWorkspaceServiceServer) mustEmbedUnimplementedWorkspaceServiceServer() {}
|
|
||||||
func (UnimplementedWorkspaceServiceServer) testEmbeddedByValue() {}
|
|
||||||
|
|
||||||
// UnsafeWorkspaceServiceServer may be embedded to opt out of forward compatibility for this service.
|
|
||||||
// Use of this interface is not recommended, as added methods to WorkspaceServiceServer will
|
|
||||||
// result in compilation errors.
|
|
||||||
type UnsafeWorkspaceServiceServer interface {
|
|
||||||
mustEmbedUnimplementedWorkspaceServiceServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterWorkspaceServiceServer(s grpc.ServiceRegistrar, srv WorkspaceServiceServer) {
|
|
||||||
// If the following call pancis, it indicates UnimplementedWorkspaceServiceServer was
|
|
||||||
// embedded by pointer and is nil. This will cause panics if an
|
|
||||||
// unimplemented method is ever invoked, so we test this at initialization
|
|
||||||
// time to prevent it from happening at runtime later due to I/O.
|
|
||||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
|
||||||
t.testEmbeddedByValue()
|
|
||||||
}
|
|
||||||
s.RegisterService(&WorkspaceService_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _WorkspaceService_GetWorkspaceProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetWorkspaceProfileRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(WorkspaceServiceServer).GetWorkspaceProfile(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: WorkspaceService_GetWorkspaceProfile_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(WorkspaceServiceServer).GetWorkspaceProfile(ctx, req.(*GetWorkspaceProfileRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _WorkspaceService_GetWorkspaceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetWorkspaceSettingRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(WorkspaceServiceServer).GetWorkspaceSetting(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: WorkspaceService_GetWorkspaceSetting_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(WorkspaceServiceServer).GetWorkspaceSetting(ctx, req.(*GetWorkspaceSettingRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _WorkspaceService_UpdateWorkspaceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(UpdateWorkspaceSettingRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(WorkspaceServiceServer).UpdateWorkspaceSetting(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: WorkspaceService_UpdateWorkspaceSetting_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(WorkspaceServiceServer).UpdateWorkspaceSetting(ctx, req.(*UpdateWorkspaceSettingRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WorkspaceService_ServiceDesc is the grpc.ServiceDesc for WorkspaceService service.
|
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
|
||||||
// and not to be introspected or modified (even as a copy)
|
|
||||||
var WorkspaceService_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "memos.api.v1.WorkspaceService",
|
|
||||||
HandlerType: (*WorkspaceServiceServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "GetWorkspaceProfile",
|
|
||||||
Handler: _WorkspaceService_GetWorkspaceProfile_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetWorkspaceSetting",
|
|
||||||
Handler: _WorkspaceService_GetWorkspaceSetting_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "UpdateWorkspaceSetting",
|
|
||||||
Handler: _WorkspaceService_UpdateWorkspaceSetting_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "api/v1/workspace_service.proto",
|
|
||||||
}
|
|
||||||
|
|
@ -304,7 +304,7 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Status'
|
$ref: '#/components/schemas/Status'
|
||||||
/api/v1/identityProviders:
|
/api/v1/identity-providers:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- IdentityProviderService
|
- IdentityProviderService
|
||||||
|
|
@ -355,16 +355,16 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Status'
|
$ref: '#/components/schemas/Status'
|
||||||
/api/v1/identityProviders/{identityProvider}:
|
/api/v1/identity-providers/{identity-provider}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- IdentityProviderService
|
- IdentityProviderService
|
||||||
description: GetIdentityProvider gets an identity provider.
|
description: GetIdentityProvider gets an identity provider.
|
||||||
operationId: IdentityProviderService_GetIdentityProvider
|
operationId: IdentityProviderService_GetIdentityProvider
|
||||||
parameters:
|
parameters:
|
||||||
- name: identityProvider
|
- name: identity-provider
|
||||||
in: path
|
in: path
|
||||||
description: The identityProvider id.
|
description: The identity-provider id.
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -387,9 +387,9 @@ paths:
|
||||||
description: DeleteIdentityProvider deletes an identity provider.
|
description: DeleteIdentityProvider deletes an identity provider.
|
||||||
operationId: IdentityProviderService_DeleteIdentityProvider
|
operationId: IdentityProviderService_DeleteIdentityProvider
|
||||||
parameters:
|
parameters:
|
||||||
- name: identityProvider
|
- name: identity-provider
|
||||||
in: path
|
in: path
|
||||||
description: The identityProvider id.
|
description: The identity-provider id.
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -409,9 +409,9 @@ paths:
|
||||||
description: UpdateIdentityProvider updates an identity provider.
|
description: UpdateIdentityProvider updates an identity provider.
|
||||||
operationId: IdentityProviderService_UpdateIdentityProvider
|
operationId: IdentityProviderService_UpdateIdentityProvider
|
||||||
parameters:
|
parameters:
|
||||||
- name: identityProvider
|
- name: identity-provider
|
||||||
in: path
|
in: path
|
||||||
description: The identityProvider id.
|
description: The identity-provider id.
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -442,6 +442,88 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Status'
|
$ref: '#/components/schemas/Status'
|
||||||
|
/api/v1/instance/profile:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- InstanceService
|
||||||
|
description: Gets the instance profile.
|
||||||
|
operationId: InstanceService_GetInstanceProfile
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/InstanceProfile'
|
||||||
|
default:
|
||||||
|
description: Default error response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Status'
|
||||||
|
/api/v1/instance/{instance}/*:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- InstanceService
|
||||||
|
description: Gets an instance setting.
|
||||||
|
operationId: InstanceService_GetInstanceSetting
|
||||||
|
parameters:
|
||||||
|
- name: instance
|
||||||
|
in: path
|
||||||
|
description: The instance id.
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/InstanceSetting'
|
||||||
|
default:
|
||||||
|
description: Default error response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Status'
|
||||||
|
patch:
|
||||||
|
tags:
|
||||||
|
- InstanceService
|
||||||
|
description: Updates an instance setting.
|
||||||
|
operationId: InstanceService_UpdateInstanceSetting
|
||||||
|
parameters:
|
||||||
|
- name: instance
|
||||||
|
in: path
|
||||||
|
description: The instance id.
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: updateMask
|
||||||
|
in: query
|
||||||
|
description: The list of fields to update.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: field-mask
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/InstanceSetting'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/InstanceSetting'
|
||||||
|
default:
|
||||||
|
description: Default error response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Status'
|
||||||
/api/v1/memos:
|
/api/v1/memos:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
|
@ -1886,88 +1968,6 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Status'
|
$ref: '#/components/schemas/Status'
|
||||||
/api/v1/workspace/profile:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- WorkspaceService
|
|
||||||
description: Gets the workspace profile.
|
|
||||||
operationId: WorkspaceService_GetWorkspaceProfile
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/WorkspaceProfile'
|
|
||||||
default:
|
|
||||||
description: Default error response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Status'
|
|
||||||
/api/v1/workspace/{workspace}/*:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- WorkspaceService
|
|
||||||
description: Gets a workspace setting.
|
|
||||||
operationId: WorkspaceService_GetWorkspaceSetting
|
|
||||||
parameters:
|
|
||||||
- name: workspace
|
|
||||||
in: path
|
|
||||||
description: The workspace id.
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/WorkspaceSetting'
|
|
||||||
default:
|
|
||||||
description: Default error response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Status'
|
|
||||||
patch:
|
|
||||||
tags:
|
|
||||||
- WorkspaceService
|
|
||||||
description: Updates a workspace setting.
|
|
||||||
operationId: WorkspaceService_UpdateWorkspaceSetting
|
|
||||||
parameters:
|
|
||||||
- name: workspace
|
|
||||||
in: path
|
|
||||||
description: The workspace id.
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
- name: updateMask
|
|
||||||
in: query
|
|
||||||
description: The list of fields to update.
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: field-mask
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/WorkspaceSetting'
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/WorkspaceSetting'
|
|
||||||
default:
|
|
||||||
description: Default error response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Status'
|
|
||||||
/file/attachments/{attachment}/{filename:
|
/file/attachments/{attachment}/{filename:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
|
@ -2195,7 +2195,7 @@ components:
|
||||||
type: string
|
type: string
|
||||||
locale:
|
locale:
|
||||||
type: string
|
type: string
|
||||||
description: Custom profile configuration for workspace branding.
|
description: Custom profile configuration for instance branding.
|
||||||
GetCurrentSessionResponse:
|
GetCurrentSessionResponse:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|
@ -2226,7 +2226,7 @@ components:
|
||||||
type: string
|
type: string
|
||||||
description: |-
|
description: |-
|
||||||
The resource name of the identity provider.
|
The resource name of the identity provider.
|
||||||
Format: identityProviders/{idp}
|
Format: identity-providers/{idp}
|
||||||
type:
|
type:
|
||||||
enum:
|
enum:
|
||||||
- TYPE_UNSPECIFIED
|
- TYPE_UNSPECIFIED
|
||||||
|
|
@ -2249,6 +2249,138 @@ components:
|
||||||
properties:
|
properties:
|
||||||
oauth2Config:
|
oauth2Config:
|
||||||
$ref: '#/components/schemas/OAuth2Config'
|
$ref: '#/components/schemas/OAuth2Config'
|
||||||
|
InstanceProfile:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
owner:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The name of instance owner.
|
||||||
|
Format: users/{user}
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
description: Version is the current version of instance.
|
||||||
|
mode:
|
||||||
|
type: string
|
||||||
|
description: Mode is the instance mode (e.g. "prod", "dev" or "demo").
|
||||||
|
instanceUrl:
|
||||||
|
type: string
|
||||||
|
description: Instance URL is the URL of the instance.
|
||||||
|
description: Instance profile message containing basic instance information.
|
||||||
|
InstanceSetting:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The name of the instance setting.
|
||||||
|
Format: instance/settings/{setting}
|
||||||
|
generalSetting:
|
||||||
|
$ref: '#/components/schemas/InstanceSetting_GeneralSetting'
|
||||||
|
storageSetting:
|
||||||
|
$ref: '#/components/schemas/InstanceSetting_StorageSetting'
|
||||||
|
memoRelatedSetting:
|
||||||
|
$ref: '#/components/schemas/InstanceSetting_MemoRelatedSetting'
|
||||||
|
description: An instance setting resource.
|
||||||
|
InstanceSetting_GeneralSetting:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
theme:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
theme is the name of the selected theme.
|
||||||
|
This references a CSS file in the web/public/themes/ directory.
|
||||||
|
disallowUserRegistration:
|
||||||
|
type: boolean
|
||||||
|
description: disallow_user_registration disallows user registration.
|
||||||
|
disallowPasswordAuth:
|
||||||
|
type: boolean
|
||||||
|
description: disallow_password_auth disallows password authentication.
|
||||||
|
additionalScript:
|
||||||
|
type: string
|
||||||
|
description: additional_script is the additional script.
|
||||||
|
additionalStyle:
|
||||||
|
type: string
|
||||||
|
description: additional_style is the additional style.
|
||||||
|
customProfile:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/GeneralSetting_CustomProfile'
|
||||||
|
description: custom_profile is the custom profile.
|
||||||
|
weekStartDayOffset:
|
||||||
|
type: integer
|
||||||
|
description: |-
|
||||||
|
week_start_day_offset is the week start day offset from Sunday.
|
||||||
|
0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
|
||||||
|
Default is Sunday.
|
||||||
|
format: int32
|
||||||
|
disallowChangeUsername:
|
||||||
|
type: boolean
|
||||||
|
description: disallow_change_username disallows changing username.
|
||||||
|
disallowChangeNickname:
|
||||||
|
type: boolean
|
||||||
|
description: disallow_change_nickname disallows changing nickname.
|
||||||
|
description: General instance settings configuration.
|
||||||
|
InstanceSetting_MemoRelatedSetting:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
disallowPublicVisibility:
|
||||||
|
type: boolean
|
||||||
|
description: disallow_public_visibility disallows set memo as public visibility.
|
||||||
|
displayWithUpdateTime:
|
||||||
|
type: boolean
|
||||||
|
description: display_with_update_time orders and displays memo with update time.
|
||||||
|
contentLengthLimit:
|
||||||
|
type: integer
|
||||||
|
description: content_length_limit is the limit of content length. Unit is byte.
|
||||||
|
format: int32
|
||||||
|
enableDoubleClickEdit:
|
||||||
|
type: boolean
|
||||||
|
description: enable_double_click_edit enables editing on double click.
|
||||||
|
enableLinkPreview:
|
||||||
|
type: boolean
|
||||||
|
description: enable_link_preview enables links preview.
|
||||||
|
reactions:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: reactions is the list of reactions.
|
||||||
|
disableMarkdownShortcuts:
|
||||||
|
type: boolean
|
||||||
|
description: disable_markdown_shortcuts disallow the registration of markdown shortcuts.
|
||||||
|
enableBlurNsfwContent:
|
||||||
|
type: boolean
|
||||||
|
description: enable_blur_nsfw_content enables blurring of content marked as not safe for work (NSFW).
|
||||||
|
nsfwTags:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: nsfw_tags is the list of tags that mark content as NSFW for blurring.
|
||||||
|
description: Memo-related instance settings and policies.
|
||||||
|
InstanceSetting_StorageSetting:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
storageType:
|
||||||
|
enum:
|
||||||
|
- STORAGE_TYPE_UNSPECIFIED
|
||||||
|
- DATABASE
|
||||||
|
- LOCAL
|
||||||
|
- S3
|
||||||
|
type: string
|
||||||
|
description: storage_type is the storage type.
|
||||||
|
format: enum
|
||||||
|
filepathTemplate:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The template of file path.
|
||||||
|
e.g. assets/{timestamp}_{filename}
|
||||||
|
uploadSizeLimitMb:
|
||||||
|
type: string
|
||||||
|
description: The max upload size in megabytes.
|
||||||
|
s3Config:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/StorageSetting_S3Config'
|
||||||
|
description: The S3 config.
|
||||||
|
description: Storage configuration settings for instance attachments.
|
||||||
ListActivitiesResponse:
|
ListActivitiesResponse:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|
@ -3057,144 +3189,12 @@ components:
|
||||||
description: The last update time of the webhook.
|
description: The last update time of the webhook.
|
||||||
format: date-time
|
format: date-time
|
||||||
description: UserWebhook represents a webhook owned by a user.
|
description: UserWebhook represents a webhook owned by a user.
|
||||||
WorkspaceProfile:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
owner:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
The name of instance owner.
|
|
||||||
Format: users/{user}
|
|
||||||
version:
|
|
||||||
type: string
|
|
||||||
description: Version is the current version of instance.
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
description: Mode is the instance mode (e.g. "prod", "dev" or "demo").
|
|
||||||
instanceUrl:
|
|
||||||
type: string
|
|
||||||
description: Instance URL is the URL of the instance.
|
|
||||||
description: Workspace profile message containing basic workspace information.
|
|
||||||
WorkspaceSetting:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
The name of the workspace setting.
|
|
||||||
Format: workspace/settings/{setting}
|
|
||||||
generalSetting:
|
|
||||||
$ref: '#/components/schemas/WorkspaceSetting_GeneralSetting'
|
|
||||||
storageSetting:
|
|
||||||
$ref: '#/components/schemas/WorkspaceSetting_StorageSetting'
|
|
||||||
memoRelatedSetting:
|
|
||||||
$ref: '#/components/schemas/WorkspaceSetting_MemoRelatedSetting'
|
|
||||||
description: A workspace setting resource.
|
|
||||||
WorkspaceSetting_GeneralSetting:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
theme:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
theme is the name of the selected theme.
|
|
||||||
This references a CSS file in the web/public/themes/ directory.
|
|
||||||
disallowUserRegistration:
|
|
||||||
type: boolean
|
|
||||||
description: disallow_user_registration disallows user registration.
|
|
||||||
disallowPasswordAuth:
|
|
||||||
type: boolean
|
|
||||||
description: disallow_password_auth disallows password authentication.
|
|
||||||
additionalScript:
|
|
||||||
type: string
|
|
||||||
description: additional_script is the additional script.
|
|
||||||
additionalStyle:
|
|
||||||
type: string
|
|
||||||
description: additional_style is the additional style.
|
|
||||||
customProfile:
|
|
||||||
allOf:
|
|
||||||
- $ref: '#/components/schemas/GeneralSetting_CustomProfile'
|
|
||||||
description: custom_profile is the custom profile.
|
|
||||||
weekStartDayOffset:
|
|
||||||
type: integer
|
|
||||||
description: |-
|
|
||||||
week_start_day_offset is the week start day offset from Sunday.
|
|
||||||
0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
|
|
||||||
Default is Sunday.
|
|
||||||
format: int32
|
|
||||||
disallowChangeUsername:
|
|
||||||
type: boolean
|
|
||||||
description: disallow_change_username disallows changing username.
|
|
||||||
disallowChangeNickname:
|
|
||||||
type: boolean
|
|
||||||
description: disallow_change_nickname disallows changing nickname.
|
|
||||||
description: General workspace settings configuration.
|
|
||||||
WorkspaceSetting_MemoRelatedSetting:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
disallowPublicVisibility:
|
|
||||||
type: boolean
|
|
||||||
description: disallow_public_visibility disallows set memo as public visibility.
|
|
||||||
displayWithUpdateTime:
|
|
||||||
type: boolean
|
|
||||||
description: display_with_update_time orders and displays memo with update time.
|
|
||||||
contentLengthLimit:
|
|
||||||
type: integer
|
|
||||||
description: content_length_limit is the limit of content length. Unit is byte.
|
|
||||||
format: int32
|
|
||||||
enableDoubleClickEdit:
|
|
||||||
type: boolean
|
|
||||||
description: enable_double_click_edit enables editing on double click.
|
|
||||||
enableLinkPreview:
|
|
||||||
type: boolean
|
|
||||||
description: enable_link_preview enables links preview.
|
|
||||||
reactions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: reactions is the list of reactions.
|
|
||||||
disableMarkdownShortcuts:
|
|
||||||
type: boolean
|
|
||||||
description: disable_markdown_shortcuts disallow the registration of markdown shortcuts.
|
|
||||||
enableBlurNsfwContent:
|
|
||||||
type: boolean
|
|
||||||
description: enable_blur_nsfw_content enables blurring of content marked as not safe for work (NSFW).
|
|
||||||
nsfwTags:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: nsfw_tags is the list of tags that mark content as NSFW for blurring.
|
|
||||||
description: Memo-related workspace settings and policies.
|
|
||||||
WorkspaceSetting_StorageSetting:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
storageType:
|
|
||||||
enum:
|
|
||||||
- STORAGE_TYPE_UNSPECIFIED
|
|
||||||
- DATABASE
|
|
||||||
- LOCAL
|
|
||||||
- S3
|
|
||||||
type: string
|
|
||||||
description: storage_type is the storage type.
|
|
||||||
format: enum
|
|
||||||
filepathTemplate:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
The template of file path.
|
|
||||||
e.g. assets/{timestamp}_{filename}
|
|
||||||
uploadSizeLimitMb:
|
|
||||||
type: string
|
|
||||||
description: The max upload size in megabytes.
|
|
||||||
s3Config:
|
|
||||||
allOf:
|
|
||||||
- $ref: '#/components/schemas/StorageSetting_S3Config'
|
|
||||||
description: The S3 config.
|
|
||||||
description: Storage configuration settings for workspace attachments.
|
|
||||||
tags:
|
tags:
|
||||||
- name: ActivityService
|
- name: ActivityService
|
||||||
- name: AttachmentService
|
- name: AttachmentService
|
||||||
- name: AuthService
|
- name: AuthService
|
||||||
- name: IdentityProviderService
|
- name: IdentityProviderService
|
||||||
|
- name: InstanceService
|
||||||
- name: MemoService
|
- name: MemoService
|
||||||
- name: ShortcutService
|
- name: ShortcutService
|
||||||
- name: UserService
|
- name: UserService
|
||||||
- name: WorkspaceService
|
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ var File_store_attachment_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
const file_store_attachment_proto_rawDesc = "" +
|
const file_store_attachment_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x16store/attachment.proto\x12\vmemos.store\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1dstore/workspace_setting.proto\"\x8c\x02\n" +
|
"\x16store/attachment.proto\x12\vmemos.store\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cstore/instance_setting.proto\"\x8c\x02\n" +
|
||||||
"\x11AttachmentPayload\x12F\n" +
|
"\x11AttachmentPayload\x12F\n" +
|
||||||
"\ts3_object\x18\x01 \x01(\v2'.memos.store.AttachmentPayload.S3ObjectH\x00R\bs3Object\x1a\xa3\x01\n" +
|
"\ts3_object\x18\x01 \x01(\v2'.memos.store.AttachmentPayload.S3ObjectH\x00R\bs3Object\x1a\xa3\x01\n" +
|
||||||
"\bS3Object\x129\n" +
|
"\bS3Object\x129\n" +
|
||||||
|
|
@ -262,7 +262,7 @@ func file_store_attachment_proto_init() {
|
||||||
if File_store_attachment_proto != nil {
|
if File_store_attachment_proto != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
file_store_workspace_setting_proto_init()
|
file_store_instance_setting_proto_init()
|
||||||
file_store_attachment_proto_msgTypes[0].OneofWrappers = []any{
|
file_store_attachment_proto_msgTypes[0].OneofWrappers = []any{
|
||||||
(*AttachmentPayload_S3Object_)(nil),
|
(*AttachmentPayload_S3Object_)(nil),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,7 +3,7 @@ syntax = "proto3";
|
||||||
package memos.store;
|
package memos.store;
|
||||||
|
|
||||||
import "google/protobuf/timestamp.proto";
|
import "google/protobuf/timestamp.proto";
|
||||||
import "store/workspace_setting.proto";
|
import "store/instance_setting.proto";
|
||||||
|
|
||||||
option go_package = "gen/store";
|
option go_package = "gen/store";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ package memos.store;
|
||||||
|
|
||||||
option go_package = "gen/store";
|
option go_package = "gen/store";
|
||||||
|
|
||||||
enum WorkspaceSettingKey {
|
enum InstanceSettingKey {
|
||||||
WORKSPACE_SETTING_KEY_UNSPECIFIED = 0;
|
INSTANCE_SETTING_KEY_UNSPECIFIED = 0;
|
||||||
// BASIC is the key for basic settings.
|
// BASIC is the key for basic settings.
|
||||||
BASIC = 1;
|
BASIC = 1;
|
||||||
// GENERAL is the key for general settings.
|
// GENERAL is the key for general settings.
|
||||||
|
|
@ -16,24 +16,24 @@ enum WorkspaceSettingKey {
|
||||||
MEMO_RELATED = 4;
|
MEMO_RELATED = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WorkspaceSetting {
|
message InstanceSetting {
|
||||||
WorkspaceSettingKey key = 1;
|
InstanceSettingKey key = 1;
|
||||||
oneof value {
|
oneof value {
|
||||||
WorkspaceBasicSetting basic_setting = 2;
|
InstanceBasicSetting basic_setting = 2;
|
||||||
WorkspaceGeneralSetting general_setting = 3;
|
InstanceGeneralSetting general_setting = 3;
|
||||||
WorkspaceStorageSetting storage_setting = 4;
|
InstanceStorageSetting storage_setting = 4;
|
||||||
WorkspaceMemoRelatedSetting memo_related_setting = 5;
|
InstanceMemoRelatedSetting memo_related_setting = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message WorkspaceBasicSetting {
|
message InstanceBasicSetting {
|
||||||
// The secret key for workspace. Mainly used for session management.
|
// The secret key for instance. Mainly used for session management.
|
||||||
string secret_key = 1;
|
string secret_key = 1;
|
||||||
// The current schema version of database.
|
// The current schema version of database.
|
||||||
string schema_version = 2;
|
string schema_version = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WorkspaceGeneralSetting {
|
message InstanceGeneralSetting {
|
||||||
// theme is the name of the selected theme.
|
// theme is the name of the selected theme.
|
||||||
// This references a CSS file in the web/public/themes/ directory.
|
// This references a CSS file in the web/public/themes/ directory.
|
||||||
string theme = 1;
|
string theme = 1;
|
||||||
|
|
@ -46,7 +46,7 @@ message WorkspaceGeneralSetting {
|
||||||
// additional_style is the additional style.
|
// additional_style is the additional style.
|
||||||
string additional_style = 5;
|
string additional_style = 5;
|
||||||
// custom_profile is the custom profile.
|
// custom_profile is the custom profile.
|
||||||
WorkspaceCustomProfile custom_profile = 6;
|
InstanceCustomProfile custom_profile = 6;
|
||||||
// week_start_day_offset is the week start day offset from Sunday.
|
// week_start_day_offset is the week start day offset from Sunday.
|
||||||
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
|
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
|
||||||
// Default is Sunday.
|
// Default is Sunday.
|
||||||
|
|
@ -57,14 +57,14 @@ message WorkspaceGeneralSetting {
|
||||||
bool disallow_change_nickname = 9;
|
bool disallow_change_nickname = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WorkspaceCustomProfile {
|
message InstanceCustomProfile {
|
||||||
string title = 1;
|
string title = 1;
|
||||||
string description = 2;
|
string description = 2;
|
||||||
string logo_url = 3;
|
string logo_url = 3;
|
||||||
string locale = 4;
|
string locale = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WorkspaceStorageSetting {
|
message InstanceStorageSetting {
|
||||||
enum StorageType {
|
enum StorageType {
|
||||||
STORAGE_TYPE_UNSPECIFIED = 0;
|
STORAGE_TYPE_UNSPECIFIED = 0;
|
||||||
// STORAGE_TYPE_DATABASE is the database storage type.
|
// STORAGE_TYPE_DATABASE is the database storage type.
|
||||||
|
|
@ -95,7 +95,7 @@ message StorageS3Config {
|
||||||
bool use_path_style = 6;
|
bool use_path_style = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WorkspaceMemoRelatedSetting {
|
message InstanceMemoRelatedSetting {
|
||||||
// disallow_public_visibility disallows set memo as public visibility.
|
// disallow_public_visibility disallows set memo as public visibility.
|
||||||
bool disallow_public_visibility = 1;
|
bool disallow_public_visibility = 1;
|
||||||
// display_with_update_time orders and displays memo with update time.
|
// display_with_update_time orders and displays memo with update time.
|
||||||
|
|
@ -9,7 +9,6 @@ RUN --mount=type=cache,target=/go/pkg/mod \
|
||||||
--mount=type=cache,target=/root/.cache/go-build \
|
--mount=type=cache,target=/root/.cache/go-build \
|
||||||
go build -ldflags="-s -w" -o memos ./cmd/memos
|
go build -ldflags="-s -w" -o memos ./cmd/memos
|
||||||
|
|
||||||
# Make workspace with above generated files.
|
|
||||||
FROM alpine:latest AS monolithic
|
FROM alpine:latest AS monolithic
|
||||||
WORKDIR /usr/local/memos
|
WORKDIR /usr/local/memos
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
var authenticationAllowlistMethods = map[string]bool{
|
var authenticationAllowlistMethods = map[string]bool{
|
||||||
"/memos.api.v1.WorkspaceService/GetWorkspaceProfile": true,
|
"/memos.api.v1.InstanceService/GetInstanceProfile": true,
|
||||||
"/memos.api.v1.WorkspaceService/GetWorkspaceSetting": true,
|
"/memos.api.v1.InstanceService/GetInstanceSetting": true,
|
||||||
"/memos.api.v1.IdentityProviderService/ListIdentityProviders": true,
|
"/memos.api.v1.IdentityProviderService/ListIdentityProviders": true,
|
||||||
"/memos.api.v1.AuthService/CreateSession": true,
|
"/memos.api.v1.AuthService/CreateSession": true,
|
||||||
"/memos.api.v1.AuthService/GetCurrentSession": true,
|
"/memos.api.v1.AuthService/GetCurrentSession": true,
|
||||||
|
|
@ -24,7 +24,7 @@ func isUnauthorizeAllowedMethod(fullMethodName string) bool {
|
||||||
|
|
||||||
var allowedMethodsOnlyForAdmin = map[string]bool{
|
var allowedMethodsOnlyForAdmin = map[string]bool{
|
||||||
"/memos.api.v1.UserService/CreateUser": true,
|
"/memos.api.v1.UserService/CreateUser": true,
|
||||||
"/memos.api.v1.WorkspaceService/UpdateWorkspaceSetting": true,
|
"/memos.api.v1.InstanceService/UpdateInstanceSetting": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// isOnlyForAdminAllowedMethod returns true if the method is allowed to be called only by admin.
|
// isOnlyForAdminAllowedMethod returns true if the method is allowed to be called only by admin.
|
||||||
|
|
|
||||||
|
|
@ -84,12 +84,12 @@ func (s *APIV1Service) CreateAttachment(ctx context.Context, request *v1pb.Creat
|
||||||
Type: request.Attachment.Type,
|
Type: request.Attachment.Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceStorageSetting, err := s.Store.GetWorkspaceStorageSetting(ctx)
|
instanceStorageSetting, err := s.Store.GetInstanceStorageSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace storage setting: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get instance storage setting: %v", err)
|
||||||
}
|
}
|
||||||
size := binary.Size(request.Attachment.Content)
|
size := binary.Size(request.Attachment.Content)
|
||||||
uploadSizeLimit := int(workspaceStorageSetting.UploadSizeLimitMb) * MebiByte
|
uploadSizeLimit := int(instanceStorageSetting.UploadSizeLimitMb) * MebiByte
|
||||||
if uploadSizeLimit == 0 {
|
if uploadSizeLimit == 0 {
|
||||||
uploadSizeLimit = MaxUploadBufferSizeBytes
|
uploadSizeLimit = MaxUploadBufferSizeBytes
|
||||||
}
|
}
|
||||||
|
|
@ -395,15 +395,15 @@ func convertAttachmentFromStore(attachment *store.Attachment) *v1pb.Attachment {
|
||||||
|
|
||||||
// SaveAttachmentBlob save the blob of attachment based on the storage config.
|
// SaveAttachmentBlob save the blob of attachment based on the storage config.
|
||||||
func SaveAttachmentBlob(ctx context.Context, profile *profile.Profile, stores *store.Store, create *store.Attachment) error {
|
func SaveAttachmentBlob(ctx context.Context, profile *profile.Profile, stores *store.Store, create *store.Attachment) error {
|
||||||
workspaceStorageSetting, err := stores.GetWorkspaceStorageSetting(ctx)
|
instanceStorageSetting, err := stores.GetInstanceStorageSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Failed to find workspace storage setting")
|
return errors.Wrap(err, "Failed to find instance storage setting")
|
||||||
}
|
}
|
||||||
|
|
||||||
if workspaceStorageSetting.StorageType == storepb.WorkspaceStorageSetting_LOCAL {
|
if instanceStorageSetting.StorageType == storepb.InstanceStorageSetting_LOCAL {
|
||||||
filepathTemplate := "assets/{timestamp}_{filename}"
|
filepathTemplate := "assets/{timestamp}_{filename}"
|
||||||
if workspaceStorageSetting.FilepathTemplate != "" {
|
if instanceStorageSetting.FilepathTemplate != "" {
|
||||||
filepathTemplate = workspaceStorageSetting.FilepathTemplate
|
filepathTemplate = instanceStorageSetting.FilepathTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
internalPath := filepathTemplate
|
internalPath := filepathTemplate
|
||||||
|
|
@ -435,8 +435,8 @@ func SaveAttachmentBlob(ctx context.Context, profile *profile.Profile, stores *s
|
||||||
create.Reference = internalPath
|
create.Reference = internalPath
|
||||||
create.Blob = nil
|
create.Blob = nil
|
||||||
create.StorageType = storepb.AttachmentStorageType_LOCAL
|
create.StorageType = storepb.AttachmentStorageType_LOCAL
|
||||||
} else if workspaceStorageSetting.StorageType == storepb.WorkspaceStorageSetting_S3 {
|
} else if instanceStorageSetting.StorageType == storepb.InstanceStorageSetting_S3 {
|
||||||
s3Config := workspaceStorageSetting.S3Config
|
s3Config := instanceStorageSetting.S3Config
|
||||||
if s3Config == nil {
|
if s3Config == nil {
|
||||||
return errors.Errorf("No actived external storage found")
|
return errors.Errorf("No actived external storage found")
|
||||||
}
|
}
|
||||||
|
|
@ -445,7 +445,7 @@ func SaveAttachmentBlob(ctx context.Context, profile *profile.Profile, stores *s
|
||||||
return errors.Wrap(err, "Failed to create s3 client")
|
return errors.Wrap(err, "Failed to create s3 client")
|
||||||
}
|
}
|
||||||
|
|
||||||
filepathTemplate := workspaceStorageSetting.FilepathTemplate
|
filepathTemplate := instanceStorageSetting.FilepathTemplate
|
||||||
if !strings.Contains(filepathTemplate, "{filename}") {
|
if !strings.Contains(filepathTemplate, "{filename}") {
|
||||||
filepathTemplate = filepath.Join(filepathTemplate, "{filename}")
|
filepathTemplate = filepath.Join(filepathTemplate, "{filename}")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,12 +99,12 @@ func (s *APIV1Service) CreateSession(ctx context.Context, request *v1pb.CreateSe
|
||||||
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(passwordCredentials.Password)); err != nil {
|
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(passwordCredentials.Password)); err != nil {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, unmatchedUsernameAndPasswordError)
|
return nil, status.Errorf(codes.InvalidArgument, unmatchedUsernameAndPasswordError)
|
||||||
}
|
}
|
||||||
workspaceGeneralSetting, err := s.Store.GetWorkspaceGeneralSetting(ctx)
|
instanceGeneralSetting, err := s.Store.GetInstanceGeneralSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace general setting, error: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get instance general setting, error: %v", err)
|
||||||
}
|
}
|
||||||
// Check if the password auth in is allowed.
|
// Check if the password auth in is allowed.
|
||||||
if workspaceGeneralSetting.DisallowPasswordAuth && user.Role == store.RoleUser {
|
if instanceGeneralSetting.DisallowPasswordAuth && user.Role == store.RoleUser {
|
||||||
return nil, status.Errorf(codes.PermissionDenied, "password signin is not allowed")
|
return nil, status.Errorf(codes.PermissionDenied, "password signin is not allowed")
|
||||||
}
|
}
|
||||||
existingUser = user
|
existingUser = user
|
||||||
|
|
@ -155,11 +155,11 @@ func (s *APIV1Service) CreateSession(ctx context.Context, request *v1pb.CreateSe
|
||||||
}
|
}
|
||||||
if user == nil {
|
if user == nil {
|
||||||
// Check if the user is allowed to sign up.
|
// Check if the user is allowed to sign up.
|
||||||
workspaceGeneralSetting, err := s.Store.GetWorkspaceGeneralSetting(ctx)
|
instanceGeneralSetting, err := s.Store.GetInstanceGeneralSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace general setting, error: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get instance general setting, error: %v", err)
|
||||||
}
|
}
|
||||||
if workspaceGeneralSetting.DisallowUserRegistration {
|
if instanceGeneralSetting.DisallowUserRegistration {
|
||||||
return nil, status.Errorf(codes.PermissionDenied, "user registration is not allowed")
|
return nil, status.Errorf(codes.PermissionDenied, "user registration is not allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ import (
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetWorkspaceProfile returns the workspace profile.
|
// GetInstanceProfile returns the instance profile.
|
||||||
func (s *APIV1Service) GetWorkspaceProfile(ctx context.Context, _ *v1pb.GetWorkspaceProfileRequest) (*v1pb.WorkspaceProfile, error) {
|
func (s *APIV1Service) GetInstanceProfile(ctx context.Context, _ *v1pb.GetInstanceProfileRequest) (*v1pb.InstanceProfile, error) {
|
||||||
workspaceProfile := &v1pb.WorkspaceProfile{
|
instanceProfile := &v1pb.InstanceProfile{
|
||||||
Version: s.Profile.Version,
|
Version: s.Profile.Version,
|
||||||
Mode: s.Profile.Mode,
|
Mode: s.Profile.Mode,
|
||||||
InstanceUrl: s.Profile.InstanceURL,
|
InstanceUrl: s.Profile.InstanceURL,
|
||||||
|
|
@ -25,47 +25,47 @@ func (s *APIV1Service) GetWorkspaceProfile(ctx context.Context, _ *v1pb.GetWorks
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get instance owner: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get instance owner: %v", err)
|
||||||
}
|
}
|
||||||
if owner != nil {
|
if owner != nil {
|
||||||
workspaceProfile.Owner = owner.Name
|
instanceProfile.Owner = owner.Name
|
||||||
}
|
}
|
||||||
return workspaceProfile, nil
|
return instanceProfile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIV1Service) GetWorkspaceSetting(ctx context.Context, request *v1pb.GetWorkspaceSettingRequest) (*v1pb.WorkspaceSetting, error) {
|
func (s *APIV1Service) GetInstanceSetting(ctx context.Context, request *v1pb.GetInstanceSettingRequest) (*v1pb.InstanceSetting, error) {
|
||||||
workspaceSettingKeyString, err := ExtractWorkspaceSettingKeyFromName(request.Name)
|
instanceSettingKeyString, err := ExtractInstanceSettingKeyFromName(request.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "invalid workspace setting name: %v", err)
|
return nil, status.Errorf(codes.InvalidArgument, "invalid instance setting name: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceSettingKey := storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[workspaceSettingKeyString])
|
instanceSettingKey := storepb.InstanceSettingKey(storepb.InstanceSettingKey_value[instanceSettingKeyString])
|
||||||
// Get workspace setting from store with default value.
|
// Get instance setting from store with default value.
|
||||||
switch workspaceSettingKey {
|
switch instanceSettingKey {
|
||||||
case storepb.WorkspaceSettingKey_BASIC:
|
case storepb.InstanceSettingKey_BASIC:
|
||||||
_, err = s.Store.GetWorkspaceBasicSetting(ctx)
|
_, err = s.Store.GetInstanceBasicSetting(ctx)
|
||||||
case storepb.WorkspaceSettingKey_GENERAL:
|
case storepb.InstanceSettingKey_GENERAL:
|
||||||
_, err = s.Store.GetWorkspaceGeneralSetting(ctx)
|
_, err = s.Store.GetInstanceGeneralSetting(ctx)
|
||||||
case storepb.WorkspaceSettingKey_MEMO_RELATED:
|
case storepb.InstanceSettingKey_MEMO_RELATED:
|
||||||
_, err = s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
_, err = s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
case storepb.WorkspaceSettingKey_STORAGE:
|
case storepb.InstanceSettingKey_STORAGE:
|
||||||
_, err = s.Store.GetWorkspaceStorageSetting(ctx)
|
_, err = s.Store.GetInstanceStorageSetting(ctx)
|
||||||
default:
|
default:
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "unsupported workspace setting key: %v", workspaceSettingKey)
|
return nil, status.Errorf(codes.InvalidArgument, "unsupported instance setting key: %v", instanceSettingKey)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace setting: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get instance setting: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
|
instanceSetting, err := s.Store.GetInstanceSetting(ctx, &store.FindInstanceSetting{
|
||||||
Name: workspaceSettingKey.String(),
|
Name: instanceSettingKey.String(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace setting: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get instance setting: %v", err)
|
||||||
}
|
}
|
||||||
if workspaceSetting == nil {
|
if instanceSetting == nil {
|
||||||
return nil, status.Errorf(codes.NotFound, "workspace setting not found")
|
return nil, status.Errorf(codes.NotFound, "instance setting not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// For storage setting, only host can get it.
|
// For storage setting, only host can get it.
|
||||||
if workspaceSetting.Key == storepb.WorkspaceSettingKey_STORAGE {
|
if instanceSetting.Key == storepb.InstanceSettingKey_STORAGE {
|
||||||
user, err := s.GetCurrentUser(ctx)
|
user, err := s.GetCurrentUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
|
||||||
|
|
@ -75,10 +75,10 @@ func (s *APIV1Service) GetWorkspaceSetting(ctx context.Context, request *v1pb.Ge
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertWorkspaceSettingFromStore(workspaceSetting), nil
|
return convertInstanceSettingFromStore(instanceSetting), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIV1Service) UpdateWorkspaceSetting(ctx context.Context, request *v1pb.UpdateWorkspaceSettingRequest) (*v1pb.WorkspaceSetting, error) {
|
func (s *APIV1Service) UpdateInstanceSetting(ctx context.Context, request *v1pb.UpdateInstanceSettingRequest) (*v1pb.InstanceSetting, error) {
|
||||||
user, err := s.GetCurrentUser(ctx)
|
user, err := s.GetCurrentUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
|
||||||
|
|
@ -93,64 +93,64 @@ func (s *APIV1Service) UpdateWorkspaceSetting(ctx context.Context, request *v1pb
|
||||||
// TODO: Apply update_mask if specified
|
// TODO: Apply update_mask if specified
|
||||||
_ = request.UpdateMask
|
_ = request.UpdateMask
|
||||||
|
|
||||||
updateSetting := convertWorkspaceSettingToStore(request.Setting)
|
updateSetting := convertInstanceSettingToStore(request.Setting)
|
||||||
workspaceSetting, err := s.Store.UpsertWorkspaceSetting(ctx, updateSetting)
|
instanceSetting, err := s.Store.UpsertInstanceSetting(ctx, updateSetting)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to upsert workspace setting: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to upsert instance setting: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertWorkspaceSettingFromStore(workspaceSetting), nil
|
return convertInstanceSettingFromStore(instanceSetting), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertWorkspaceSettingFromStore(setting *storepb.WorkspaceSetting) *v1pb.WorkspaceSetting {
|
func convertInstanceSettingFromStore(setting *storepb.InstanceSetting) *v1pb.InstanceSetting {
|
||||||
workspaceSetting := &v1pb.WorkspaceSetting{
|
instanceSetting := &v1pb.InstanceSetting{
|
||||||
Name: fmt.Sprintf("workspace/settings/%s", setting.Key.String()),
|
Name: fmt.Sprintf("instance/settings/%s", setting.Key.String()),
|
||||||
}
|
}
|
||||||
switch setting.Value.(type) {
|
switch setting.Value.(type) {
|
||||||
case *storepb.WorkspaceSetting_GeneralSetting:
|
case *storepb.InstanceSetting_GeneralSetting:
|
||||||
workspaceSetting.Value = &v1pb.WorkspaceSetting_GeneralSetting_{
|
instanceSetting.Value = &v1pb.InstanceSetting_GeneralSetting_{
|
||||||
GeneralSetting: convertWorkspaceGeneralSettingFromStore(setting.GetGeneralSetting()),
|
GeneralSetting: convertInstanceGeneralSettingFromStore(setting.GetGeneralSetting()),
|
||||||
}
|
}
|
||||||
case *storepb.WorkspaceSetting_StorageSetting:
|
case *storepb.InstanceSetting_StorageSetting:
|
||||||
workspaceSetting.Value = &v1pb.WorkspaceSetting_StorageSetting_{
|
instanceSetting.Value = &v1pb.InstanceSetting_StorageSetting_{
|
||||||
StorageSetting: convertWorkspaceStorageSettingFromStore(setting.GetStorageSetting()),
|
StorageSetting: convertInstanceStorageSettingFromStore(setting.GetStorageSetting()),
|
||||||
}
|
}
|
||||||
case *storepb.WorkspaceSetting_MemoRelatedSetting:
|
case *storepb.InstanceSetting_MemoRelatedSetting:
|
||||||
workspaceSetting.Value = &v1pb.WorkspaceSetting_MemoRelatedSetting_{
|
instanceSetting.Value = &v1pb.InstanceSetting_MemoRelatedSetting_{
|
||||||
MemoRelatedSetting: convertWorkspaceMemoRelatedSettingFromStore(setting.GetMemoRelatedSetting()),
|
MemoRelatedSetting: convertInstanceMemoRelatedSettingFromStore(setting.GetMemoRelatedSetting()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return workspaceSetting
|
return instanceSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertWorkspaceSettingToStore(setting *v1pb.WorkspaceSetting) *storepb.WorkspaceSetting {
|
func convertInstanceSettingToStore(setting *v1pb.InstanceSetting) *storepb.InstanceSetting {
|
||||||
settingKeyString, _ := ExtractWorkspaceSettingKeyFromName(setting.Name)
|
settingKeyString, _ := ExtractInstanceSettingKeyFromName(setting.Name)
|
||||||
workspaceSetting := &storepb.WorkspaceSetting{
|
instanceSetting := &storepb.InstanceSetting{
|
||||||
Key: storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[settingKeyString]),
|
Key: storepb.InstanceSettingKey(storepb.InstanceSettingKey_value[settingKeyString]),
|
||||||
Value: &storepb.WorkspaceSetting_GeneralSetting{
|
Value: &storepb.InstanceSetting_GeneralSetting{
|
||||||
GeneralSetting: convertWorkspaceGeneralSettingToStore(setting.GetGeneralSetting()),
|
GeneralSetting: convertInstanceGeneralSettingToStore(setting.GetGeneralSetting()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
switch workspaceSetting.Key {
|
switch instanceSetting.Key {
|
||||||
case storepb.WorkspaceSettingKey_GENERAL:
|
case storepb.InstanceSettingKey_GENERAL:
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_GeneralSetting{
|
instanceSetting.Value = &storepb.InstanceSetting_GeneralSetting{
|
||||||
GeneralSetting: convertWorkspaceGeneralSettingToStore(setting.GetGeneralSetting()),
|
GeneralSetting: convertInstanceGeneralSettingToStore(setting.GetGeneralSetting()),
|
||||||
}
|
}
|
||||||
case storepb.WorkspaceSettingKey_STORAGE:
|
case storepb.InstanceSettingKey_STORAGE:
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_StorageSetting{
|
instanceSetting.Value = &storepb.InstanceSetting_StorageSetting{
|
||||||
StorageSetting: convertWorkspaceStorageSettingToStore(setting.GetStorageSetting()),
|
StorageSetting: convertInstanceStorageSettingToStore(setting.GetStorageSetting()),
|
||||||
}
|
}
|
||||||
case storepb.WorkspaceSettingKey_MEMO_RELATED:
|
case storepb.InstanceSettingKey_MEMO_RELATED:
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_MemoRelatedSetting{
|
instanceSetting.Value = &storepb.InstanceSetting_MemoRelatedSetting{
|
||||||
MemoRelatedSetting: convertWorkspaceMemoRelatedSettingToStore(setting.GetMemoRelatedSetting()),
|
MemoRelatedSetting: convertInstanceMemoRelatedSettingToStore(setting.GetMemoRelatedSetting()),
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// Keep the default GeneralSetting value
|
// Keep the default GeneralSetting value
|
||||||
}
|
}
|
||||||
return workspaceSetting
|
return instanceSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSetting) *v1pb.WorkspaceSetting_GeneralSetting {
|
func convertInstanceGeneralSettingFromStore(setting *storepb.InstanceGeneralSetting) *v1pb.InstanceSetting_GeneralSetting {
|
||||||
if setting == nil {
|
if setting == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -160,7 +160,7 @@ func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSe
|
||||||
theme = "default"
|
theme = "default"
|
||||||
}
|
}
|
||||||
|
|
||||||
generalSetting := &v1pb.WorkspaceSetting_GeneralSetting{
|
generalSetting := &v1pb.InstanceSetting_GeneralSetting{
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
DisallowUserRegistration: setting.DisallowUserRegistration,
|
DisallowUserRegistration: setting.DisallowUserRegistration,
|
||||||
DisallowPasswordAuth: setting.DisallowPasswordAuth,
|
DisallowPasswordAuth: setting.DisallowPasswordAuth,
|
||||||
|
|
@ -171,7 +171,7 @@ func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSe
|
||||||
DisallowChangeNickname: setting.DisallowChangeNickname,
|
DisallowChangeNickname: setting.DisallowChangeNickname,
|
||||||
}
|
}
|
||||||
if setting.CustomProfile != nil {
|
if setting.CustomProfile != nil {
|
||||||
generalSetting.CustomProfile = &v1pb.WorkspaceSetting_GeneralSetting_CustomProfile{
|
generalSetting.CustomProfile = &v1pb.InstanceSetting_GeneralSetting_CustomProfile{
|
||||||
Title: setting.CustomProfile.Title,
|
Title: setting.CustomProfile.Title,
|
||||||
Description: setting.CustomProfile.Description,
|
Description: setting.CustomProfile.Description,
|
||||||
LogoUrl: setting.CustomProfile.LogoUrl,
|
LogoUrl: setting.CustomProfile.LogoUrl,
|
||||||
|
|
@ -181,11 +181,11 @@ func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSe
|
||||||
return generalSetting
|
return generalSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertWorkspaceGeneralSettingToStore(setting *v1pb.WorkspaceSetting_GeneralSetting) *storepb.WorkspaceGeneralSetting {
|
func convertInstanceGeneralSettingToStore(setting *v1pb.InstanceSetting_GeneralSetting) *storepb.InstanceGeneralSetting {
|
||||||
if setting == nil {
|
if setting == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
generalSetting := &storepb.WorkspaceGeneralSetting{
|
generalSetting := &storepb.InstanceGeneralSetting{
|
||||||
Theme: setting.Theme,
|
Theme: setting.Theme,
|
||||||
DisallowUserRegistration: setting.DisallowUserRegistration,
|
DisallowUserRegistration: setting.DisallowUserRegistration,
|
||||||
DisallowPasswordAuth: setting.DisallowPasswordAuth,
|
DisallowPasswordAuth: setting.DisallowPasswordAuth,
|
||||||
|
|
@ -196,7 +196,7 @@ func convertWorkspaceGeneralSettingToStore(setting *v1pb.WorkspaceSetting_Genera
|
||||||
DisallowChangeNickname: setting.DisallowChangeNickname,
|
DisallowChangeNickname: setting.DisallowChangeNickname,
|
||||||
}
|
}
|
||||||
if setting.CustomProfile != nil {
|
if setting.CustomProfile != nil {
|
||||||
generalSetting.CustomProfile = &storepb.WorkspaceCustomProfile{
|
generalSetting.CustomProfile = &storepb.InstanceCustomProfile{
|
||||||
Title: setting.CustomProfile.Title,
|
Title: setting.CustomProfile.Title,
|
||||||
Description: setting.CustomProfile.Description,
|
Description: setting.CustomProfile.Description,
|
||||||
LogoUrl: setting.CustomProfile.LogoUrl,
|
LogoUrl: setting.CustomProfile.LogoUrl,
|
||||||
|
|
@ -206,17 +206,17 @@ func convertWorkspaceGeneralSettingToStore(setting *v1pb.WorkspaceSetting_Genera
|
||||||
return generalSetting
|
return generalSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertWorkspaceStorageSettingFromStore(settingpb *storepb.WorkspaceStorageSetting) *v1pb.WorkspaceSetting_StorageSetting {
|
func convertInstanceStorageSettingFromStore(settingpb *storepb.InstanceStorageSetting) *v1pb.InstanceSetting_StorageSetting {
|
||||||
if settingpb == nil {
|
if settingpb == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
setting := &v1pb.WorkspaceSetting_StorageSetting{
|
setting := &v1pb.InstanceSetting_StorageSetting{
|
||||||
StorageType: v1pb.WorkspaceSetting_StorageSetting_StorageType(settingpb.StorageType),
|
StorageType: v1pb.InstanceSetting_StorageSetting_StorageType(settingpb.StorageType),
|
||||||
FilepathTemplate: settingpb.FilepathTemplate,
|
FilepathTemplate: settingpb.FilepathTemplate,
|
||||||
UploadSizeLimitMb: settingpb.UploadSizeLimitMb,
|
UploadSizeLimitMb: settingpb.UploadSizeLimitMb,
|
||||||
}
|
}
|
||||||
if settingpb.S3Config != nil {
|
if settingpb.S3Config != nil {
|
||||||
setting.S3Config = &v1pb.WorkspaceSetting_StorageSetting_S3Config{
|
setting.S3Config = &v1pb.InstanceSetting_StorageSetting_S3Config{
|
||||||
AccessKeyId: settingpb.S3Config.AccessKeyId,
|
AccessKeyId: settingpb.S3Config.AccessKeyId,
|
||||||
AccessKeySecret: settingpb.S3Config.AccessKeySecret,
|
AccessKeySecret: settingpb.S3Config.AccessKeySecret,
|
||||||
Endpoint: settingpb.S3Config.Endpoint,
|
Endpoint: settingpb.S3Config.Endpoint,
|
||||||
|
|
@ -228,12 +228,12 @@ func convertWorkspaceStorageSettingFromStore(settingpb *storepb.WorkspaceStorage
|
||||||
return setting
|
return setting
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertWorkspaceStorageSettingToStore(setting *v1pb.WorkspaceSetting_StorageSetting) *storepb.WorkspaceStorageSetting {
|
func convertInstanceStorageSettingToStore(setting *v1pb.InstanceSetting_StorageSetting) *storepb.InstanceStorageSetting {
|
||||||
if setting == nil {
|
if setting == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
settingpb := &storepb.WorkspaceStorageSetting{
|
settingpb := &storepb.InstanceStorageSetting{
|
||||||
StorageType: storepb.WorkspaceStorageSetting_StorageType(setting.StorageType),
|
StorageType: storepb.InstanceStorageSetting_StorageType(setting.StorageType),
|
||||||
FilepathTemplate: setting.FilepathTemplate,
|
FilepathTemplate: setting.FilepathTemplate,
|
||||||
UploadSizeLimitMb: setting.UploadSizeLimitMb,
|
UploadSizeLimitMb: setting.UploadSizeLimitMb,
|
||||||
}
|
}
|
||||||
|
|
@ -250,11 +250,11 @@ func convertWorkspaceStorageSettingToStore(setting *v1pb.WorkspaceSetting_Storag
|
||||||
return settingpb
|
return settingpb
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertWorkspaceMemoRelatedSettingFromStore(setting *storepb.WorkspaceMemoRelatedSetting) *v1pb.WorkspaceSetting_MemoRelatedSetting {
|
func convertInstanceMemoRelatedSettingFromStore(setting *storepb.InstanceMemoRelatedSetting) *v1pb.InstanceSetting_MemoRelatedSetting {
|
||||||
if setting == nil {
|
if setting == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &v1pb.WorkspaceSetting_MemoRelatedSetting{
|
return &v1pb.InstanceSetting_MemoRelatedSetting{
|
||||||
DisallowPublicVisibility: setting.DisallowPublicVisibility,
|
DisallowPublicVisibility: setting.DisallowPublicVisibility,
|
||||||
DisplayWithUpdateTime: setting.DisplayWithUpdateTime,
|
DisplayWithUpdateTime: setting.DisplayWithUpdateTime,
|
||||||
ContentLengthLimit: setting.ContentLengthLimit,
|
ContentLengthLimit: setting.ContentLengthLimit,
|
||||||
|
|
@ -267,11 +267,11 @@ func convertWorkspaceMemoRelatedSettingFromStore(setting *storepb.WorkspaceMemoR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertWorkspaceMemoRelatedSettingToStore(setting *v1pb.WorkspaceSetting_MemoRelatedSetting) *storepb.WorkspaceMemoRelatedSetting {
|
func convertInstanceMemoRelatedSettingToStore(setting *v1pb.InstanceSetting_MemoRelatedSetting) *storepb.InstanceMemoRelatedSetting {
|
||||||
if setting == nil {
|
if setting == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &storepb.WorkspaceMemoRelatedSetting{
|
return &storepb.InstanceMemoRelatedSetting{
|
||||||
DisallowPublicVisibility: setting.DisallowPublicVisibility,
|
DisallowPublicVisibility: setting.DisallowPublicVisibility,
|
||||||
DisplayWithUpdateTime: setting.DisplayWithUpdateTime,
|
DisplayWithUpdateTime: setting.DisplayWithUpdateTime,
|
||||||
ContentLengthLimit: setting.ContentLengthLimit,
|
ContentLengthLimit: setting.ContentLengthLimit,
|
||||||
|
|
@ -35,11 +35,11 @@ func (s *APIV1Service) CreateMemo(ctx context.Context, request *v1pb.CreateMemoR
|
||||||
Content: request.Memo.Content,
|
Content: request.Memo.Content,
|
||||||
Visibility: convertVisibilityToStore(request.Memo.Visibility),
|
Visibility: convertVisibilityToStore(request.Memo.Visibility),
|
||||||
}
|
}
|
||||||
workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace memo related setting")
|
return nil, status.Errorf(codes.Internal, "failed to get instance memo related setting")
|
||||||
}
|
}
|
||||||
if workspaceMemoRelatedSetting.DisallowPublicVisibility && create.Visibility == store.Public {
|
if instanceMemoRelatedSetting.DisallowPublicVisibility && create.Visibility == store.Public {
|
||||||
return nil, status.Errorf(codes.PermissionDenied, "disable public memos system setting is enabled")
|
return nil, status.Errorf(codes.PermissionDenied, "disable public memos system setting is enabled")
|
||||||
}
|
}
|
||||||
contentLengthLimit, err := s.getContentLengthLimit(ctx)
|
contentLengthLimit, err := s.getContentLengthLimit(ctx)
|
||||||
|
|
@ -147,11 +147,11 @@ func (s *APIV1Service) ListMemos(ctx context.Context, request *v1pb.ListMemosReq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace memo related setting")
|
return nil, status.Errorf(codes.Internal, "failed to get instance memo related setting")
|
||||||
}
|
}
|
||||||
if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
|
if instanceMemoRelatedSetting.DisplayWithUpdateTime {
|
||||||
memoFind.OrderByUpdatedTs = true
|
memoFind.OrderByUpdatedTs = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,12 +340,12 @@ func (s *APIV1Service) UpdateMemo(ctx context.Context, request *v1pb.UpdateMemoR
|
||||||
update.Content = &memo.Content
|
update.Content = &memo.Content
|
||||||
update.Payload = memo.Payload
|
update.Payload = memo.Payload
|
||||||
} else if path == "visibility" {
|
} else if path == "visibility" {
|
||||||
workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace memo related setting")
|
return nil, status.Errorf(codes.Internal, "failed to get instance memo related setting")
|
||||||
}
|
}
|
||||||
visibility := convertVisibilityToStore(request.Memo.Visibility)
|
visibility := convertVisibilityToStore(request.Memo.Visibility)
|
||||||
if workspaceMemoRelatedSetting.DisallowPublicVisibility && visibility == store.Public {
|
if instanceMemoRelatedSetting.DisallowPublicVisibility && visibility == store.Public {
|
||||||
return nil, status.Errorf(codes.PermissionDenied, "disable public memos system setting is enabled")
|
return nil, status.Errorf(codes.PermissionDenied, "disable public memos system setting is enabled")
|
||||||
}
|
}
|
||||||
update.Visibility = &visibility
|
update.Visibility = &visibility
|
||||||
|
|
@ -365,9 +365,9 @@ func (s *APIV1Service) UpdateMemo(ctx context.Context, request *v1pb.UpdateMemoR
|
||||||
update.UpdatedTs = &updatedTs
|
update.UpdatedTs = &updatedTs
|
||||||
} else if path == "display_time" {
|
} else if path == "display_time" {
|
||||||
displayTs := request.Memo.DisplayTime.AsTime().Unix()
|
displayTs := request.Memo.DisplayTime.AsTime().Unix()
|
||||||
memoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
memoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace memo related setting")
|
return nil, status.Errorf(codes.Internal, "failed to get instance memo related setting")
|
||||||
}
|
}
|
||||||
if memoRelatedSetting.DisplayWithUpdateTime {
|
if memoRelatedSetting.DisplayWithUpdateTime {
|
||||||
update.UpdatedTs = &displayTs
|
update.UpdatedTs = &displayTs
|
||||||
|
|
@ -680,11 +680,11 @@ func (s *APIV1Service) ListMemoComments(ctx context.Context, request *v1pb.ListM
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIV1Service) getContentLengthLimit(ctx context.Context) (int, error) {
|
func (s *APIV1Service) getContentLengthLimit(ctx context.Context) (int, error) {
|
||||||
workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, status.Errorf(codes.Internal, "failed to get workspace memo related setting")
|
return 0, status.Errorf(codes.Internal, "failed to get instance memo related setting")
|
||||||
}
|
}
|
||||||
return int(workspaceMemoRelatedSetting.ContentLengthLimit), nil
|
return int(instanceMemoRelatedSetting.ContentLengthLimit), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DispatchMemoCreatedWebhook dispatches webhook when memo is created.
|
// DispatchMemoCreatedWebhook dispatches webhook when memo is created.
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ import (
|
||||||
|
|
||||||
func (s *APIV1Service) convertMemoFromStore(ctx context.Context, memo *store.Memo, reactions []*store.Reaction, attachments []*store.Attachment) (*v1pb.Memo, error) {
|
func (s *APIV1Service) convertMemoFromStore(ctx context.Context, memo *store.Memo, reactions []*store.Reaction, attachments []*store.Attachment) (*v1pb.Memo, error) {
|
||||||
displayTs := memo.CreatedTs
|
displayTs := memo.CreatedTs
|
||||||
workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get workspace memo related setting")
|
return nil, errors.Wrap(err, "failed to get instance memo related setting")
|
||||||
}
|
}
|
||||||
if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
|
if instanceMemoRelatedSetting.DisplayWithUpdateTime {
|
||||||
displayTs = memo.UpdatedTs
|
displayTs = memo.UpdatedTs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
WorkspaceSettingNamePrefix = "workspace/settings/"
|
InstanceSettingNamePrefix = "instance/settings/"
|
||||||
UserNamePrefix = "users/"
|
UserNamePrefix = "users/"
|
||||||
MemoNamePrefix = "memos/"
|
MemoNamePrefix = "memos/"
|
||||||
AttachmentNamePrefix = "attachments/"
|
AttachmentNamePrefix = "attachments/"
|
||||||
|
|
@ -41,20 +41,20 @@ func GetNameParentTokens(name string, tokenPrefixes ...string) ([]string, error)
|
||||||
return tokens, nil
|
return tokens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractWorkspaceSettingKeyFromName(name string) (string, error) {
|
func ExtractInstanceSettingKeyFromName(name string) (string, error) {
|
||||||
const prefix = "workspace/settings/"
|
const prefix = "instance/settings/"
|
||||||
if !strings.HasPrefix(name, prefix) {
|
if !strings.HasPrefix(name, prefix) {
|
||||||
return "", errors.Errorf("invalid workspace setting name: expected prefix %q, got %q", prefix, name)
|
return "", errors.Errorf("invalid instance setting name: expected prefix %q, got %q", prefix, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
settingKey := strings.TrimPrefix(name, prefix)
|
settingKey := strings.TrimPrefix(name, prefix)
|
||||||
if settingKey == "" {
|
if settingKey == "" {
|
||||||
return "", errors.Errorf("invalid workspace setting name: empty setting key in %q", name)
|
return "", errors.Errorf("invalid instance setting name: empty setting key in %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure there are no additional path segments
|
// Ensure there are no additional path segments
|
||||||
if strings.Contains(settingKey, "/") {
|
if strings.Contains(settingKey, "/") {
|
||||||
return "", errors.Errorf("invalid workspace setting name: setting key cannot contain '/' in %q", name)
|
return "", errors.Errorf("invalid instance setting name: setting key cannot contain '/' in %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return settingKey, nil
|
return settingKey, nil
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,17 @@ import (
|
||||||
v1pb "github.com/usememos/memos/proto/gen/api/v1"
|
v1pb "github.com/usememos/memos/proto/gen/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetWorkspaceProfile(t *testing.T) {
|
func TestGetInstanceProfile(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
t.Run("GetWorkspaceProfile returns workspace profile", func(t *testing.T) {
|
t.Run("GetInstanceProfile returns instance profile", func(t *testing.T) {
|
||||||
// Create test service for this specific test
|
// Create test service for this specific test
|
||||||
ts := NewTestService(t)
|
ts := NewTestService(t)
|
||||||
defer ts.Cleanup()
|
defer ts.Cleanup()
|
||||||
|
|
||||||
// Call GetWorkspaceProfile directly
|
// Call GetInstanceProfile directly
|
||||||
req := &v1pb.GetWorkspaceProfileRequest{}
|
req := &v1pb.GetInstanceProfileRequest{}
|
||||||
resp, err := ts.Service.GetWorkspaceProfile(ctx, req)
|
resp, err := ts.Service.GetInstanceProfile(ctx, req)
|
||||||
|
|
||||||
// Verify response
|
// Verify response
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
@ -35,7 +35,7 @@ func TestGetWorkspaceProfile(t *testing.T) {
|
||||||
require.Empty(t, resp.Owner)
|
require.Empty(t, resp.Owner)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("GetWorkspaceProfile with owner", func(t *testing.T) {
|
t.Run("GetInstanceProfile with owner", func(t *testing.T) {
|
||||||
// Create test service for this specific test
|
// Create test service for this specific test
|
||||||
ts := NewTestService(t)
|
ts := NewTestService(t)
|
||||||
defer ts.Cleanup()
|
defer ts.Cleanup()
|
||||||
|
|
@ -45,9 +45,9 @@ func TestGetWorkspaceProfile(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, hostUser)
|
require.NotNil(t, hostUser)
|
||||||
|
|
||||||
// Call GetWorkspaceProfile directly
|
// Call GetInstanceProfile directly
|
||||||
req := &v1pb.GetWorkspaceProfileRequest{}
|
req := &v1pb.GetInstanceProfileRequest{}
|
||||||
resp, err := ts.Service.GetWorkspaceProfile(ctx, req)
|
resp, err := ts.Service.GetInstanceProfile(ctx, req)
|
||||||
|
|
||||||
// Verify response
|
// Verify response
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
@ -64,7 +64,7 @@ func TestGetWorkspaceProfile(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetWorkspaceProfile_Concurrency(t *testing.T) {
|
func TestGetInstanceProfile_Concurrency(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
t.Run("Concurrent access to service", func(t *testing.T) {
|
t.Run("Concurrent access to service", func(t *testing.T) {
|
||||||
|
|
@ -79,13 +79,13 @@ func TestGetWorkspaceProfile_Concurrency(t *testing.T) {
|
||||||
|
|
||||||
// Make concurrent requests
|
// Make concurrent requests
|
||||||
numGoroutines := 10
|
numGoroutines := 10
|
||||||
results := make(chan *v1pb.WorkspaceProfile, numGoroutines)
|
results := make(chan *v1pb.InstanceProfile, numGoroutines)
|
||||||
errors := make(chan error, numGoroutines)
|
errors := make(chan error, numGoroutines)
|
||||||
|
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for i := 0; i < numGoroutines; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
req := &v1pb.GetWorkspaceProfileRequest{}
|
req := &v1pb.GetInstanceProfileRequest{}
|
||||||
resp, err := ts.Service.GetWorkspaceProfile(ctx, req)
|
resp, err := ts.Service.GetInstanceProfile(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors <- err
|
errors <- err
|
||||||
return
|
return
|
||||||
|
|
@ -110,24 +110,24 @@ func TestGetWorkspaceProfile_Concurrency(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetWorkspaceSetting(t *testing.T) {
|
func TestGetInstanceSetting(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
t.Run("GetWorkspaceSetting - general setting", func(t *testing.T) {
|
t.Run("GetInstanceSetting - general setting", func(t *testing.T) {
|
||||||
// Create test service for this specific test
|
// Create test service for this specific test
|
||||||
ts := NewTestService(t)
|
ts := NewTestService(t)
|
||||||
defer ts.Cleanup()
|
defer ts.Cleanup()
|
||||||
|
|
||||||
// Call GetWorkspaceSetting for general setting
|
// Call GetInstanceSetting for general setting
|
||||||
req := &v1pb.GetWorkspaceSettingRequest{
|
req := &v1pb.GetInstanceSettingRequest{
|
||||||
Name: "workspace/settings/GENERAL",
|
Name: "instance/settings/GENERAL",
|
||||||
}
|
}
|
||||||
resp, err := ts.Service.GetWorkspaceSetting(ctx, req)
|
resp, err := ts.Service.GetInstanceSetting(ctx, req)
|
||||||
|
|
||||||
// Verify response
|
// Verify response
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
require.Equal(t, "workspace/settings/GENERAL", resp.Name)
|
require.Equal(t, "instance/settings/GENERAL", resp.Name)
|
||||||
|
|
||||||
// The general setting should have a general_setting field
|
// The general setting should have a general_setting field
|
||||||
generalSetting := resp.GetGeneralSetting()
|
generalSetting := resp.GetGeneralSetting()
|
||||||
|
|
@ -139,7 +139,7 @@ func TestGetWorkspaceSetting(t *testing.T) {
|
||||||
require.Empty(t, generalSetting.AdditionalScript)
|
require.Empty(t, generalSetting.AdditionalScript)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("GetWorkspaceSetting - storage setting", func(t *testing.T) {
|
t.Run("GetInstanceSetting - storage setting", func(t *testing.T) {
|
||||||
// Create test service for this specific test
|
// Create test service for this specific test
|
||||||
ts := NewTestService(t)
|
ts := NewTestService(t)
|
||||||
defer ts.Cleanup()
|
defer ts.Cleanup()
|
||||||
|
|
@ -151,56 +151,56 @@ func TestGetWorkspaceSetting(t *testing.T) {
|
||||||
// Add user to context
|
// Add user to context
|
||||||
userCtx := ts.CreateUserContext(ctx, hostUser.ID)
|
userCtx := ts.CreateUserContext(ctx, hostUser.ID)
|
||||||
|
|
||||||
// Call GetWorkspaceSetting for storage setting
|
// Call GetInstanceSetting for storage setting
|
||||||
req := &v1pb.GetWorkspaceSettingRequest{
|
req := &v1pb.GetInstanceSettingRequest{
|
||||||
Name: "workspace/settings/STORAGE",
|
Name: "instance/settings/STORAGE",
|
||||||
}
|
}
|
||||||
resp, err := ts.Service.GetWorkspaceSetting(userCtx, req)
|
resp, err := ts.Service.GetInstanceSetting(userCtx, req)
|
||||||
|
|
||||||
// Verify response
|
// Verify response
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
require.Equal(t, "workspace/settings/STORAGE", resp.Name)
|
require.Equal(t, "instance/settings/STORAGE", resp.Name)
|
||||||
|
|
||||||
// The storage setting should have a storage_setting field
|
// The storage setting should have a storage_setting field
|
||||||
storageSetting := resp.GetStorageSetting()
|
storageSetting := resp.GetStorageSetting()
|
||||||
require.NotNil(t, storageSetting)
|
require.NotNil(t, storageSetting)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("GetWorkspaceSetting - memo related setting", func(t *testing.T) {
|
t.Run("GetInstanceSetting - memo related setting", func(t *testing.T) {
|
||||||
// Create test service for this specific test
|
// Create test service for this specific test
|
||||||
ts := NewTestService(t)
|
ts := NewTestService(t)
|
||||||
defer ts.Cleanup()
|
defer ts.Cleanup()
|
||||||
|
|
||||||
// Call GetWorkspaceSetting for memo related setting
|
// Call GetInstanceSetting for memo related setting
|
||||||
req := &v1pb.GetWorkspaceSettingRequest{
|
req := &v1pb.GetInstanceSettingRequest{
|
||||||
Name: "workspace/settings/MEMO_RELATED",
|
Name: "instance/settings/MEMO_RELATED",
|
||||||
}
|
}
|
||||||
resp, err := ts.Service.GetWorkspaceSetting(ctx, req)
|
resp, err := ts.Service.GetInstanceSetting(ctx, req)
|
||||||
|
|
||||||
// Verify response
|
// Verify response
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
require.Equal(t, "workspace/settings/MEMO_RELATED", resp.Name)
|
require.Equal(t, "instance/settings/MEMO_RELATED", resp.Name)
|
||||||
|
|
||||||
// The memo related setting should have a memo_related_setting field
|
// The memo related setting should have a memo_related_setting field
|
||||||
memoRelatedSetting := resp.GetMemoRelatedSetting()
|
memoRelatedSetting := resp.GetMemoRelatedSetting()
|
||||||
require.NotNil(t, memoRelatedSetting)
|
require.NotNil(t, memoRelatedSetting)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("GetWorkspaceSetting - invalid setting name", func(t *testing.T) {
|
t.Run("GetInstanceSetting - invalid setting name", func(t *testing.T) {
|
||||||
// Create test service for this specific test
|
// Create test service for this specific test
|
||||||
ts := NewTestService(t)
|
ts := NewTestService(t)
|
||||||
defer ts.Cleanup()
|
defer ts.Cleanup()
|
||||||
|
|
||||||
// Call GetWorkspaceSetting with invalid name
|
// Call GetInstanceSetting with invalid name
|
||||||
req := &v1pb.GetWorkspaceSettingRequest{
|
req := &v1pb.GetInstanceSettingRequest{
|
||||||
Name: "invalid/setting/name",
|
Name: "invalid/setting/name",
|
||||||
}
|
}
|
||||||
_, err := ts.Service.GetWorkspaceSetting(ctx, req)
|
_, err := ts.Service.GetInstanceSetting(ctx, req)
|
||||||
|
|
||||||
// Should return an error
|
// Should return an error
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Contains(t, err.Error(), "invalid workspace setting name")
|
require.Contains(t, err.Error(), "invalid instance setting name")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -241,14 +241,14 @@ func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserR
|
||||||
ID: user.ID,
|
ID: user.ID,
|
||||||
UpdatedTs: ¤tTs,
|
UpdatedTs: ¤tTs,
|
||||||
}
|
}
|
||||||
workspaceGeneralSetting, err := s.Store.GetWorkspaceGeneralSetting(ctx)
|
instanceGeneralSetting, err := s.Store.GetInstanceGeneralSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to get workspace general setting: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to get instance general setting: %v", err)
|
||||||
}
|
}
|
||||||
for _, field := range request.UpdateMask.Paths {
|
for _, field := range request.UpdateMask.Paths {
|
||||||
switch field {
|
switch field {
|
||||||
case "username":
|
case "username":
|
||||||
if workspaceGeneralSetting.DisallowChangeUsername {
|
if instanceGeneralSetting.DisallowChangeUsername {
|
||||||
return nil, status.Errorf(codes.PermissionDenied, "permission denied: disallow change username")
|
return nil, status.Errorf(codes.PermissionDenied, "permission denied: disallow change username")
|
||||||
}
|
}
|
||||||
if !base.UIDMatcher.MatchString(strings.ToLower(request.User.Username)) {
|
if !base.UIDMatcher.MatchString(strings.ToLower(request.User.Username)) {
|
||||||
|
|
@ -256,7 +256,7 @@ func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserR
|
||||||
}
|
}
|
||||||
update.Username = &request.User.Username
|
update.Username = &request.User.Username
|
||||||
case "display_name":
|
case "display_name":
|
||||||
if workspaceGeneralSetting.DisallowChangeNickname {
|
if instanceGeneralSetting.DisallowChangeNickname {
|
||||||
return nil, status.Errorf(codes.PermissionDenied, "permission denied: disallow change nickname")
|
return nil, status.Errorf(codes.PermissionDenied, "permission denied: disallow change nickname")
|
||||||
}
|
}
|
||||||
update.Nickname = &request.User.DisplayName
|
update.Nickname = &request.User.DisplayName
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *APIV1Service) ListAllUserStats(ctx context.Context, _ *v1pb.ListAllUserStatsRequest) (*v1pb.ListAllUserStatsResponse, error) {
|
func (s *APIV1Service) ListAllUserStats(ctx context.Context, _ *v1pb.ListAllUserStatsRequest) (*v1pb.ListAllUserStatsResponse, error) {
|
||||||
workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get workspace memo related setting")
|
return nil, errors.Wrap(err, "failed to get instance memo related setting")
|
||||||
}
|
}
|
||||||
|
|
||||||
normalStatus := store.Normal
|
normalStatus := store.Normal
|
||||||
|
|
@ -50,7 +50,7 @@ func (s *APIV1Service) ListAllUserStats(ctx context.Context, _ *v1pb.ListAllUser
|
||||||
userMemoStatMap := make(map[int32]*v1pb.UserStats)
|
userMemoStatMap := make(map[int32]*v1pb.UserStats)
|
||||||
for _, memo := range memos {
|
for _, memo := range memos {
|
||||||
displayTs := memo.CreatedTs
|
displayTs := memo.CreatedTs
|
||||||
if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
|
if instanceMemoRelatedSetting.DisplayWithUpdateTime {
|
||||||
displayTs = memo.UpdatedTs
|
displayTs = memo.UpdatedTs
|
||||||
}
|
}
|
||||||
userMemoStatMap[memo.CreatorID] = &v1pb.UserStats{
|
userMemoStatMap[memo.CreatorID] = &v1pb.UserStats{
|
||||||
|
|
@ -101,9 +101,9 @@ func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserSt
|
||||||
return nil, status.Errorf(codes.Internal, "failed to list memos: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to list memos: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
|
instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get workspace memo related setting")
|
return nil, errors.Wrap(err, "failed to get instance memo related setting")
|
||||||
}
|
}
|
||||||
|
|
||||||
displayTimestamps := []*timestamppb.Timestamp{}
|
displayTimestamps := []*timestamppb.Timestamp{}
|
||||||
|
|
@ -116,7 +116,7 @@ func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserSt
|
||||||
|
|
||||||
for _, memo := range memos {
|
for _, memo := range memos {
|
||||||
displayTs := memo.CreatedTs
|
displayTs := memo.CreatedTs
|
||||||
if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
|
if instanceMemoRelatedSetting.DisplayWithUpdateTime {
|
||||||
displayTs = memo.UpdatedTs
|
displayTs = memo.UpdatedTs
|
||||||
}
|
}
|
||||||
displayTimestamps = append(displayTimestamps, timestamppb.New(time.Unix(displayTs, 0)))
|
displayTimestamps = append(displayTimestamps, timestamppb.New(time.Unix(displayTs, 0)))
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
type APIV1Service struct {
|
type APIV1Service struct {
|
||||||
grpc_health_v1.UnimplementedHealthServer
|
grpc_health_v1.UnimplementedHealthServer
|
||||||
|
|
||||||
v1pb.UnimplementedWorkspaceServiceServer
|
v1pb.UnimplementedInstanceServiceServer
|
||||||
v1pb.UnimplementedAuthServiceServer
|
v1pb.UnimplementedAuthServiceServer
|
||||||
v1pb.UnimplementedUserServiceServer
|
v1pb.UnimplementedUserServiceServer
|
||||||
v1pb.UnimplementedMemoServiceServer
|
v1pb.UnimplementedMemoServiceServer
|
||||||
|
|
@ -53,7 +53,7 @@ func NewAPIV1Service(secret string, profile *profile.Profile, store *store.Store
|
||||||
grpcServer: grpcServer,
|
grpcServer: grpcServer,
|
||||||
}
|
}
|
||||||
grpc_health_v1.RegisterHealthServer(grpcServer, apiv1Service)
|
grpc_health_v1.RegisterHealthServer(grpcServer, apiv1Service)
|
||||||
v1pb.RegisterWorkspaceServiceServer(grpcServer, apiv1Service)
|
v1pb.RegisterInstanceServiceServer(grpcServer, apiv1Service)
|
||||||
v1pb.RegisterAuthServiceServer(grpcServer, apiv1Service)
|
v1pb.RegisterAuthServiceServer(grpcServer, apiv1Service)
|
||||||
v1pb.RegisterUserServiceServer(grpcServer, apiv1Service)
|
v1pb.RegisterUserServiceServer(grpcServer, apiv1Service)
|
||||||
v1pb.RegisterMemoServiceServer(grpcServer, apiv1Service)
|
v1pb.RegisterMemoServiceServer(grpcServer, apiv1Service)
|
||||||
|
|
@ -87,7 +87,7 @@ func (s *APIV1Service) RegisterGateway(ctx context.Context, echoServer *echo.Ech
|
||||||
}
|
}
|
||||||
|
|
||||||
gwMux := runtime.NewServeMux()
|
gwMux := runtime.NewServeMux()
|
||||||
if err := v1pb.RegisterWorkspaceServiceHandler(ctx, gwMux, conn); err != nil {
|
if err := v1pb.RegisterInstanceServiceHandler(ctx, gwMux, conn); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := v1pb.RegisterAuthServiceHandler(ctx, gwMux, conn); err != nil {
|
if err := v1pb.RegisterAuthServiceHandler(ctx, gwMux, conn); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ func (s *RSSService) getRSSItemDescription(content string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRSSHeading(ctx context.Context, stores *store.Store) (RSSHeading, error) {
|
func getRSSHeading(ctx context.Context, stores *store.Store) (RSSHeading, error) {
|
||||||
settings, err := stores.GetWorkspaceGeneralSetting(ctx)
|
settings, err := stores.GetInstanceGeneralSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return RSSHeading{}, err
|
return RSSHeading{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ func (r *Runner) RunOnce(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runner) CheckAndPresign(ctx context.Context) {
|
func (r *Runner) CheckAndPresign(ctx context.Context) {
|
||||||
workspaceStorageSetting, err := r.Store.GetWorkspaceStorageSetting(ctx)
|
instanceStorageSetting, err := r.Store.GetInstanceStorageSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +88,7 @@ func (r *Runner) CheckAndPresign(ctx context.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s3Config := workspaceStorageSetting.GetS3Config()
|
s3Config := instanceStorageSetting.GetS3Config()
|
||||||
if s3ObjectPayload.S3Config != nil {
|
if s3ObjectPayload.S3Config != nil {
|
||||||
s3Config = s3ObjectPayload.S3Config
|
s3Config = s3ObjectPayload.S3Config
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,14 +60,14 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
||||||
s.profiler.StartMemoryMonitor(ctx)
|
s.profiler.StartMemoryMonitor(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceBasicSetting, err := s.getOrUpsertWorkspaceBasicSetting(ctx)
|
instanceBasicSetting, err := s.getOrUpsertInstanceBasicSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get workspace basic setting")
|
return nil, errors.Wrap(err, "failed to get instance basic setting")
|
||||||
}
|
}
|
||||||
|
|
||||||
secret := "usememos"
|
secret := "usememos"
|
||||||
if profile.Mode == "prod" {
|
if profile.Mode == "prod" {
|
||||||
secret = workspaceBasicSetting.SecretKey
|
secret = instanceBasicSetting.SecretKey
|
||||||
}
|
}
|
||||||
s.Secret = secret
|
s.Secret = secret
|
||||||
|
|
||||||
|
|
@ -229,27 +229,27 @@ func (s *Server) StartBackgroundRunners(ctx context.Context) {
|
||||||
slog.Info("background runners started", "goroutines", runtime.NumGoroutine())
|
slog.Info("background runners started", "goroutines", runtime.NumGoroutine())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getOrUpsertWorkspaceBasicSetting(ctx context.Context) (*storepb.WorkspaceBasicSetting, error) {
|
func (s *Server) getOrUpsertInstanceBasicSetting(ctx context.Context) (*storepb.InstanceBasicSetting, error) {
|
||||||
workspaceBasicSetting, err := s.Store.GetWorkspaceBasicSetting(ctx)
|
instanceBasicSetting, err := s.Store.GetInstanceBasicSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get workspace basic setting")
|
return nil, errors.Wrap(err, "failed to get instance basic setting")
|
||||||
}
|
}
|
||||||
modified := false
|
modified := false
|
||||||
if workspaceBasicSetting.SecretKey == "" {
|
if instanceBasicSetting.SecretKey == "" {
|
||||||
workspaceBasicSetting.SecretKey = uuid.NewString()
|
instanceBasicSetting.SecretKey = uuid.NewString()
|
||||||
modified = true
|
modified = true
|
||||||
}
|
}
|
||||||
if modified {
|
if modified {
|
||||||
workspaceSetting, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{
|
instanceSetting, err := s.Store.UpsertInstanceSetting(ctx, &storepb.InstanceSetting{
|
||||||
Key: storepb.WorkspaceSettingKey_BASIC,
|
Key: storepb.InstanceSettingKey_BASIC,
|
||||||
Value: &storepb.WorkspaceSetting_BasicSetting{BasicSetting: workspaceBasicSetting},
|
Value: &storepb.InstanceSetting_BasicSetting{BasicSetting: instanceBasicSetting},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to upsert workspace setting")
|
return nil, errors.Wrap(err, "failed to upsert instance setting")
|
||||||
}
|
}
|
||||||
workspaceBasicSetting = workspaceSetting.GetBasicSetting()
|
instanceBasicSetting = instanceSetting.GetBasicSetting()
|
||||||
}
|
}
|
||||||
return workspaceBasicSetting, nil
|
return instanceBasicSetting, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// stacktraceError wraps an underlying error and captures the stacktrace. It
|
// stacktraceError wraps an underlying error and captures the stacktrace. It
|
||||||
|
|
|
||||||
|
|
@ -141,16 +141,16 @@ func (s *Store) DeleteAttachment(ctx context.Context, delete *DeleteAttachment)
|
||||||
if s3ObjectPayload == nil {
|
if s3ObjectPayload == nil {
|
||||||
return errors.Errorf("No s3 object found")
|
return errors.Errorf("No s3 object found")
|
||||||
}
|
}
|
||||||
workspaceStorageSetting, err := s.GetWorkspaceStorageSetting(ctx)
|
instanceStorageSetting, err := s.GetInstanceStorageSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get workspace storage setting")
|
return errors.Wrap(err, "failed to get instance storage setting")
|
||||||
}
|
}
|
||||||
s3Config := s3ObjectPayload.S3Config
|
s3Config := s3ObjectPayload.S3Config
|
||||||
if s3Config == nil {
|
if s3Config == nil {
|
||||||
if workspaceStorageSetting.S3Config == nil {
|
if instanceStorageSetting.S3Config == nil {
|
||||||
return errors.Errorf("S3 config is not found")
|
return errors.Errorf("S3 config is not found")
|
||||||
}
|
}
|
||||||
s3Config = workspaceStorageSetting.S3Config
|
s3Config = instanceStorageSetting.S3Config
|
||||||
}
|
}
|
||||||
|
|
||||||
s3Client, err := s3.NewClient(ctx, s3Config)
|
s3Client, err := s3.NewClient(ctx, s3Config)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.WorkspaceSetting) (*store.WorkspaceSetting, error) {
|
func (d *DB) UpsertInstanceSetting(ctx context.Context, upsert *store.InstanceSetting) (*store.InstanceSetting, error) {
|
||||||
stmt := "INSERT INTO `system_setting` (`name`, `value`, `description`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `value` = ?, `description` = ?"
|
stmt := "INSERT INTO `system_setting` (`name`, `value`, `description`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `value` = ?, `description` = ?"
|
||||||
_, err := d.db.ExecContext(
|
_, err := d.db.ExecContext(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -25,7 +25,7 @@ func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.Workspace
|
||||||
return upsert, nil
|
return upsert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspaceSetting) ([]*store.WorkspaceSetting, error) {
|
func (d *DB) ListInstanceSettings(ctx context.Context, find *store.FindInstanceSetting) ([]*store.InstanceSetting, error) {
|
||||||
where, args := []string{"1 = 1"}, []any{}
|
where, args := []string{"1 = 1"}, []any{}
|
||||||
if find.Name != "" {
|
if find.Name != "" {
|
||||||
where, args = append(where, "`name` = ?"), append(args, find.Name)
|
where, args = append(where, "`name` = ?"), append(args, find.Name)
|
||||||
|
|
@ -38,9 +38,9 @@ func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspac
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
list := []*store.WorkspaceSetting{}
|
list := []*store.InstanceSetting{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
systemSettingMessage := &store.WorkspaceSetting{}
|
systemSettingMessage := &store.InstanceSetting{}
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&systemSettingMessage.Name,
|
&systemSettingMessage.Name,
|
||||||
&systemSettingMessage.Value,
|
&systemSettingMessage.Value,
|
||||||
|
|
@ -58,7 +58,7 @@ func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspac
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DB) DeleteWorkspaceSetting(ctx context.Context, delete *store.DeleteWorkspaceSetting) error {
|
func (d *DB) DeleteInstanceSetting(ctx context.Context, delete *store.DeleteInstanceSetting) error {
|
||||||
stmt := "DELETE FROM `system_setting` WHERE `name` = ?"
|
stmt := "DELETE FROM `system_setting` WHERE `name` = ?"
|
||||||
_, err := d.db.ExecContext(ctx, stmt, delete.Name)
|
_, err := d.db.ExecContext(ctx, stmt, delete.Name)
|
||||||
return err
|
return err
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.WorkspaceSetting) (*store.WorkspaceSetting, error) {
|
func (d *DB) UpsertInstanceSetting(ctx context.Context, upsert *store.InstanceSetting) (*store.InstanceSetting, error) {
|
||||||
stmt := `
|
stmt := `
|
||||||
INSERT INTO system_setting (
|
INSERT INTO system_setting (
|
||||||
name, value, description
|
name, value, description
|
||||||
|
|
@ -25,7 +25,7 @@ func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.Workspace
|
||||||
return upsert, nil
|
return upsert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspaceSetting) ([]*store.WorkspaceSetting, error) {
|
func (d *DB) ListInstanceSettings(ctx context.Context, find *store.FindInstanceSetting) ([]*store.InstanceSetting, error) {
|
||||||
where, args := []string{"1 = 1"}, []any{}
|
where, args := []string{"1 = 1"}, []any{}
|
||||||
if find.Name != "" {
|
if find.Name != "" {
|
||||||
where, args = append(where, "name = "+placeholder(len(args)+1)), append(args, find.Name)
|
where, args = append(where, "name = "+placeholder(len(args)+1)), append(args, find.Name)
|
||||||
|
|
@ -45,9 +45,9 @@ func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspac
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
list := []*store.WorkspaceSetting{}
|
list := []*store.InstanceSetting{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
systemSettingMessage := &store.WorkspaceSetting{}
|
systemSettingMessage := &store.InstanceSetting{}
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&systemSettingMessage.Name,
|
&systemSettingMessage.Name,
|
||||||
&systemSettingMessage.Value,
|
&systemSettingMessage.Value,
|
||||||
|
|
@ -65,7 +65,7 @@ func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspac
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DB) DeleteWorkspaceSetting(ctx context.Context, delete *store.DeleteWorkspaceSetting) error {
|
func (d *DB) DeleteInstanceSetting(ctx context.Context, delete *store.DeleteInstanceSetting) error {
|
||||||
stmt := `DELETE FROM system_setting WHERE name = $1`
|
stmt := `DELETE FROM system_setting WHERE name = $1`
|
||||||
_, err := d.db.ExecContext(ctx, stmt, delete.Name)
|
_, err := d.db.ExecContext(ctx, stmt, delete.Name)
|
||||||
return err
|
return err
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.WorkspaceSetting) (*store.WorkspaceSetting, error) {
|
func (d *DB) UpsertInstanceSetting(ctx context.Context, upsert *store.InstanceSetting) (*store.InstanceSetting, error) {
|
||||||
stmt := `
|
stmt := `
|
||||||
INSERT INTO system_setting (
|
INSERT INTO system_setting (
|
||||||
name, value, description
|
name, value, description
|
||||||
|
|
@ -25,7 +25,7 @@ func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.Workspace
|
||||||
return upsert, nil
|
return upsert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspaceSetting) ([]*store.WorkspaceSetting, error) {
|
func (d *DB) ListInstanceSettings(ctx context.Context, find *store.FindInstanceSetting) ([]*store.InstanceSetting, error) {
|
||||||
where, args := []string{"1 = 1"}, []any{}
|
where, args := []string{"1 = 1"}, []any{}
|
||||||
if find.Name != "" {
|
if find.Name != "" {
|
||||||
where, args = append(where, "name = ?"), append(args, find.Name)
|
where, args = append(where, "name = ?"), append(args, find.Name)
|
||||||
|
|
@ -45,9 +45,9 @@ func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspac
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
list := []*store.WorkspaceSetting{}
|
list := []*store.InstanceSetting{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
systemSettingMessage := &store.WorkspaceSetting{}
|
systemSettingMessage := &store.InstanceSetting{}
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&systemSettingMessage.Name,
|
&systemSettingMessage.Name,
|
||||||
&systemSettingMessage.Value,
|
&systemSettingMessage.Value,
|
||||||
|
|
@ -65,7 +65,7 @@ func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspac
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DB) DeleteWorkspaceSetting(ctx context.Context, delete *store.DeleteWorkspaceSetting) error {
|
func (d *DB) DeleteInstanceSetting(ctx context.Context, delete *store.DeleteInstanceSetting) error {
|
||||||
stmt := "DELETE FROM system_setting WHERE name = ?"
|
stmt := "DELETE FROM system_setting WHERE name = ?"
|
||||||
_, err := d.db.ExecContext(ctx, stmt, delete.Name)
|
_, err := d.db.ExecContext(ctx, stmt, delete.Name)
|
||||||
return err
|
return err
|
||||||
|
|
@ -15,7 +15,7 @@ type Driver interface {
|
||||||
|
|
||||||
// MigrationHistory model related methods.
|
// MigrationHistory model related methods.
|
||||||
// NOTE: These methods are deprecated. The migration_history table is no longer used
|
// NOTE: These methods are deprecated. The migration_history table is no longer used
|
||||||
// for tracking schema versions. Schema version is now stored in workspace_setting.
|
// for tracking schema versions. Schema version is now stored in instance_setting.
|
||||||
// These methods are kept for backward compatibility to migrate existing installations.
|
// These methods are kept for backward compatibility to migrate existing installations.
|
||||||
FindMigrationHistoryList(ctx context.Context, find *FindMigrationHistory) ([]*MigrationHistory, error)
|
FindMigrationHistoryList(ctx context.Context, find *FindMigrationHistory) ([]*MigrationHistory, error)
|
||||||
UpsertMigrationHistory(ctx context.Context, upsert *UpsertMigrationHistory) (*MigrationHistory, error)
|
UpsertMigrationHistory(ctx context.Context, upsert *UpsertMigrationHistory) (*MigrationHistory, error)
|
||||||
|
|
@ -41,10 +41,10 @@ type Driver interface {
|
||||||
ListMemoRelations(ctx context.Context, find *FindMemoRelation) ([]*MemoRelation, error)
|
ListMemoRelations(ctx context.Context, find *FindMemoRelation) ([]*MemoRelation, error)
|
||||||
DeleteMemoRelation(ctx context.Context, delete *DeleteMemoRelation) error
|
DeleteMemoRelation(ctx context.Context, delete *DeleteMemoRelation) error
|
||||||
|
|
||||||
// WorkspaceSetting model related methods.
|
// InstanceSetting model related methods.
|
||||||
UpsertWorkspaceSetting(ctx context.Context, upsert *WorkspaceSetting) (*WorkspaceSetting, error)
|
UpsertInstanceSetting(ctx context.Context, upsert *InstanceSetting) (*InstanceSetting, error)
|
||||||
ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSetting) ([]*WorkspaceSetting, error)
|
ListInstanceSettings(ctx context.Context, find *FindInstanceSetting) ([]*InstanceSetting, error)
|
||||||
DeleteWorkspaceSetting(ctx context.Context, delete *DeleteWorkspaceSetting) error
|
DeleteInstanceSetting(ctx context.Context, delete *DeleteInstanceSetting) error
|
||||||
|
|
||||||
// User model related methods.
|
// User model related methods.
|
||||||
CreateUser(ctx context.Context, create *User) (*User, error)
|
CreateUser(ctx context.Context, create *User) (*User, error)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,245 @@
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
|
||||||
|
storepb "github.com/usememos/memos/proto/gen/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InstanceSetting struct {
|
||||||
|
Name string
|
||||||
|
Value string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type FindInstanceSetting struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteInstanceSetting struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpsertInstanceSetting(ctx context.Context, upsert *storepb.InstanceSetting) (*storepb.InstanceSetting, error) {
|
||||||
|
instanceSettingRaw := &InstanceSetting{
|
||||||
|
Name: upsert.Key.String(),
|
||||||
|
}
|
||||||
|
var valueBytes []byte
|
||||||
|
var err error
|
||||||
|
if upsert.Key == storepb.InstanceSettingKey_BASIC {
|
||||||
|
valueBytes, err = protojson.Marshal(upsert.GetBasicSetting())
|
||||||
|
} else if upsert.Key == storepb.InstanceSettingKey_GENERAL {
|
||||||
|
valueBytes, err = protojson.Marshal(upsert.GetGeneralSetting())
|
||||||
|
} else if upsert.Key == storepb.InstanceSettingKey_STORAGE {
|
||||||
|
valueBytes, err = protojson.Marshal(upsert.GetStorageSetting())
|
||||||
|
} else if upsert.Key == storepb.InstanceSettingKey_MEMO_RELATED {
|
||||||
|
valueBytes, err = protojson.Marshal(upsert.GetMemoRelatedSetting())
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unsupported instance setting key: %v", upsert.Key)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to marshal instance setting value")
|
||||||
|
}
|
||||||
|
valueString := string(valueBytes)
|
||||||
|
instanceSettingRaw.Value = valueString
|
||||||
|
instanceSettingRaw, err = s.driver.UpsertInstanceSetting(ctx, instanceSettingRaw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Failed to upsert instance setting")
|
||||||
|
}
|
||||||
|
instanceSetting, err := convertInstanceSettingFromRaw(instanceSettingRaw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Failed to convert instance setting")
|
||||||
|
}
|
||||||
|
s.instanceSettingCache.Set(ctx, instanceSetting.Key.String(), instanceSetting)
|
||||||
|
return instanceSetting, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) ListInstanceSettings(ctx context.Context, find *FindInstanceSetting) ([]*storepb.InstanceSetting, error) {
|
||||||
|
list, err := s.driver.ListInstanceSettings(ctx, find)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceSettings := []*storepb.InstanceSetting{}
|
||||||
|
for _, instanceSettingRaw := range list {
|
||||||
|
instanceSetting, err := convertInstanceSettingFromRaw(instanceSettingRaw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Failed to convert instance setting")
|
||||||
|
}
|
||||||
|
if instanceSetting == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s.instanceSettingCache.Set(ctx, instanceSetting.Key.String(), instanceSetting)
|
||||||
|
instanceSettings = append(instanceSettings, instanceSetting)
|
||||||
|
}
|
||||||
|
return instanceSettings, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetInstanceSetting(ctx context.Context, find *FindInstanceSetting) (*storepb.InstanceSetting, error) {
|
||||||
|
if cache, ok := s.instanceSettingCache.Get(ctx, find.Name); ok {
|
||||||
|
instanceSetting, ok := cache.(*storepb.InstanceSetting)
|
||||||
|
if ok {
|
||||||
|
return instanceSetting, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.ListInstanceSettings(ctx, find)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(list) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if len(list) > 1 {
|
||||||
|
return nil, errors.Errorf("found multiple instance settings with key %s", find.Name)
|
||||||
|
}
|
||||||
|
return list[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetInstanceBasicSetting(ctx context.Context) (*storepb.InstanceBasicSetting, error) {
|
||||||
|
instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{
|
||||||
|
Name: storepb.InstanceSettingKey_BASIC.String(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to get instance basic setting")
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceBasicSetting := &storepb.InstanceBasicSetting{}
|
||||||
|
if instanceSetting != nil {
|
||||||
|
instanceBasicSetting = instanceSetting.GetBasicSetting()
|
||||||
|
}
|
||||||
|
s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_BASIC.String(), &storepb.InstanceSetting{
|
||||||
|
Key: storepb.InstanceSettingKey_BASIC,
|
||||||
|
Value: &storepb.InstanceSetting_BasicSetting{BasicSetting: instanceBasicSetting},
|
||||||
|
})
|
||||||
|
return instanceBasicSetting, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetInstanceGeneralSetting(ctx context.Context) (*storepb.InstanceGeneralSetting, error) {
|
||||||
|
instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{
|
||||||
|
Name: storepb.InstanceSettingKey_GENERAL.String(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to get instance general setting")
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceGeneralSetting := &storepb.InstanceGeneralSetting{}
|
||||||
|
if instanceSetting != nil {
|
||||||
|
instanceGeneralSetting = instanceSetting.GetGeneralSetting()
|
||||||
|
}
|
||||||
|
s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_GENERAL.String(), &storepb.InstanceSetting{
|
||||||
|
Key: storepb.InstanceSettingKey_GENERAL,
|
||||||
|
Value: &storepb.InstanceSetting_GeneralSetting{GeneralSetting: instanceGeneralSetting},
|
||||||
|
})
|
||||||
|
return instanceGeneralSetting, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultContentLengthLimit is the default limit of content length in bytes. 8KB.
|
||||||
|
const DefaultContentLengthLimit = 8 * 1024
|
||||||
|
|
||||||
|
// DefaultReactions is the default reactions for memo related setting.
|
||||||
|
var DefaultReactions = []string{"👍", "👎", "❤️", "🎉", "😄", "😕", "😢", "😡"}
|
||||||
|
|
||||||
|
// DefaultNsfwTags is the default tags that mark content as NSFW for blurring.
|
||||||
|
var DefaultNsfwTags = []string{"nsfw"}
|
||||||
|
|
||||||
|
func (s *Store) GetInstanceMemoRelatedSetting(ctx context.Context) (*storepb.InstanceMemoRelatedSetting, error) {
|
||||||
|
instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{
|
||||||
|
Name: storepb.InstanceSettingKey_MEMO_RELATED.String(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to get instance general setting")
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceMemoRelatedSetting := &storepb.InstanceMemoRelatedSetting{}
|
||||||
|
if instanceSetting != nil {
|
||||||
|
instanceMemoRelatedSetting = instanceSetting.GetMemoRelatedSetting()
|
||||||
|
}
|
||||||
|
if instanceMemoRelatedSetting.ContentLengthLimit < DefaultContentLengthLimit {
|
||||||
|
instanceMemoRelatedSetting.ContentLengthLimit = DefaultContentLengthLimit
|
||||||
|
}
|
||||||
|
if len(instanceMemoRelatedSetting.Reactions) == 0 {
|
||||||
|
instanceMemoRelatedSetting.Reactions = append(instanceMemoRelatedSetting.Reactions, DefaultReactions...)
|
||||||
|
}
|
||||||
|
if len(instanceMemoRelatedSetting.NsfwTags) == 0 {
|
||||||
|
instanceMemoRelatedSetting.NsfwTags = append(instanceMemoRelatedSetting.NsfwTags, DefaultNsfwTags...)
|
||||||
|
}
|
||||||
|
s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_MEMO_RELATED.String(), &storepb.InstanceSetting{
|
||||||
|
Key: storepb.InstanceSettingKey_MEMO_RELATED,
|
||||||
|
Value: &storepb.InstanceSetting_MemoRelatedSetting{MemoRelatedSetting: instanceMemoRelatedSetting},
|
||||||
|
})
|
||||||
|
return instanceMemoRelatedSetting, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultInstanceStorageType = storepb.InstanceStorageSetting_DATABASE
|
||||||
|
defaultInstanceUploadSizeLimitMb = 30
|
||||||
|
defaultInstanceFilepathTemplate = "assets/{timestamp}_{filename}"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Store) GetInstanceStorageSetting(ctx context.Context) (*storepb.InstanceStorageSetting, error) {
|
||||||
|
instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{
|
||||||
|
Name: storepb.InstanceSettingKey_STORAGE.String(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to get instance storage setting")
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceStorageSetting := &storepb.InstanceStorageSetting{}
|
||||||
|
if instanceSetting != nil {
|
||||||
|
instanceStorageSetting = instanceSetting.GetStorageSetting()
|
||||||
|
}
|
||||||
|
if instanceStorageSetting.StorageType == storepb.InstanceStorageSetting_STORAGE_TYPE_UNSPECIFIED {
|
||||||
|
instanceStorageSetting.StorageType = defaultInstanceStorageType
|
||||||
|
}
|
||||||
|
if instanceStorageSetting.UploadSizeLimitMb == 0 {
|
||||||
|
instanceStorageSetting.UploadSizeLimitMb = defaultInstanceUploadSizeLimitMb
|
||||||
|
}
|
||||||
|
if instanceStorageSetting.FilepathTemplate == "" {
|
||||||
|
instanceStorageSetting.FilepathTemplate = defaultInstanceFilepathTemplate
|
||||||
|
}
|
||||||
|
s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_STORAGE.String(), &storepb.InstanceSetting{
|
||||||
|
Key: storepb.InstanceSettingKey_STORAGE,
|
||||||
|
Value: &storepb.InstanceSetting_StorageSetting{StorageSetting: instanceStorageSetting},
|
||||||
|
})
|
||||||
|
return instanceStorageSetting, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertInstanceSettingFromRaw(instanceSettingRaw *InstanceSetting) (*storepb.InstanceSetting, error) {
|
||||||
|
instanceSetting := &storepb.InstanceSetting{
|
||||||
|
Key: storepb.InstanceSettingKey(storepb.InstanceSettingKey_value[instanceSettingRaw.Name]),
|
||||||
|
}
|
||||||
|
switch instanceSettingRaw.Name {
|
||||||
|
case storepb.InstanceSettingKey_BASIC.String():
|
||||||
|
basicSetting := &storepb.InstanceBasicSetting{}
|
||||||
|
if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), basicSetting); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
instanceSetting.Value = &storepb.InstanceSetting_BasicSetting{BasicSetting: basicSetting}
|
||||||
|
case storepb.InstanceSettingKey_GENERAL.String():
|
||||||
|
generalSetting := &storepb.InstanceGeneralSetting{}
|
||||||
|
if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), generalSetting); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
instanceSetting.Value = &storepb.InstanceSetting_GeneralSetting{GeneralSetting: generalSetting}
|
||||||
|
case storepb.InstanceSettingKey_STORAGE.String():
|
||||||
|
storageSetting := &storepb.InstanceStorageSetting{}
|
||||||
|
if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), storageSetting); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
instanceSetting.Value = &storepb.InstanceSetting_StorageSetting{StorageSetting: storageSetting}
|
||||||
|
case storepb.InstanceSettingKey_MEMO_RELATED.String():
|
||||||
|
memoRelatedSetting := &storepb.InstanceMemoRelatedSetting{}
|
||||||
|
if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), memoRelatedSetting); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
instanceSetting.Value = &storepb.InstanceSetting_MemoRelatedSetting{MemoRelatedSetting: memoRelatedSetting}
|
||||||
|
default:
|
||||||
|
// Skip unsupported instance setting key.
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return instanceSetting, nil
|
||||||
|
}
|
||||||
|
|
@ -2,8 +2,8 @@ package store
|
||||||
|
|
||||||
// MigrationHistory represents a record in the migration_history table.
|
// MigrationHistory represents a record in the migration_history table.
|
||||||
// NOTE: The migration_history table is deprecated in favor of storing schema version
|
// NOTE: The migration_history table is deprecated in favor of storing schema version
|
||||||
// in workspace_setting (BASIC setting). This is kept for backward compatibility only.
|
// in system_setting (BASIC setting). This is kept for backward compatibility only.
|
||||||
// Migration from migration_history to workspace_setting happens automatically during startup.
|
// Migration from migration_history to system_setting happens automatically during startup.
|
||||||
type MigrationHistory struct {
|
type MigrationHistory struct {
|
||||||
Version string
|
Version string
|
||||||
CreatedTs int64
|
CreatedTs int64
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,19 @@ import (
|
||||||
// Migration System Overview:
|
// Migration System Overview:
|
||||||
//
|
//
|
||||||
// The migration system handles database schema versioning and upgrades.
|
// The migration system handles database schema versioning and upgrades.
|
||||||
// Schema version is stored in workspace_setting (the new system).
|
// Schema version is stored in system_setting (the new system).
|
||||||
// The old migration_history table is deprecated but still supported for backward compatibility.
|
// The old migration_history table is deprecated but still supported for backward compatibility.
|
||||||
//
|
//
|
||||||
// Migration Flow:
|
// Migration Flow:
|
||||||
// 1. preMigrate: Check if DB is initialized. If not, apply LATEST.sql
|
// 1. preMigrate: Check if DB is initialized. If not, apply LATEST.sql
|
||||||
// 2. normalizeMigrationHistoryList: Normalize old migration_history records (for pre-0.22 installations)
|
// 2. normalizeMigrationHistoryList: Normalize old migration_history records (for pre-0.22 installations)
|
||||||
// 3. migrateSchemaVersionToSetting: Migrate version from migration_history to workspace_setting
|
// 3. migrateSchemaVersionToSetting: Migrate version from migration_history to system_setting
|
||||||
// 4. Migrate (prod mode): Apply incremental migrations from current to target version
|
// 4. Migrate (prod mode): Apply incremental migrations from current to target version
|
||||||
// 5. Migrate (demo mode): Seed database with demo data
|
// 5. Migrate (demo mode): Seed database with demo data
|
||||||
//
|
//
|
||||||
// Version Tracking:
|
// Version Tracking:
|
||||||
// - New installations: Schema version set in workspace_setting immediately
|
// - New installations: Schema version set in system_setting immediately
|
||||||
// - Old installations: Version migrated from migration_history to workspace_setting automatically
|
// - Old installations: Version migrated from migration_history to system_setting automatically
|
||||||
// - Empty version: Treated as 0.0.0 and all migrations applied
|
// - Empty version: Treated as 0.0.0 and all migrations applied
|
||||||
//
|
//
|
||||||
// Migration Files:
|
// Migration Files:
|
||||||
|
|
@ -118,25 +118,25 @@ func (s *Store) Migrate(ctx context.Context) error {
|
||||||
|
|
||||||
switch s.profile.Mode {
|
switch s.profile.Mode {
|
||||||
case modeProd:
|
case modeProd:
|
||||||
workspaceBasicSetting, err := s.GetWorkspaceBasicSetting(ctx)
|
instanceBasicSetting, err := s.GetInstanceBasicSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get workspace basic setting")
|
return errors.Wrap(err, "failed to get instance basic setting")
|
||||||
}
|
}
|
||||||
currentSchemaVersion, err := s.GetCurrentSchemaVersion()
|
currentSchemaVersion, err := s.GetCurrentSchemaVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get current schema version")
|
return errors.Wrap(err, "failed to get current schema version")
|
||||||
}
|
}
|
||||||
// Check for downgrade (but skip if schema version is empty - that means fresh/old installation)
|
// Check for downgrade (but skip if schema version is empty - that means fresh/old installation)
|
||||||
if !isVersionEmpty(workspaceBasicSetting.SchemaVersion) && version.IsVersionGreaterThan(workspaceBasicSetting.SchemaVersion, currentSchemaVersion) {
|
if !isVersionEmpty(instanceBasicSetting.SchemaVersion) && version.IsVersionGreaterThan(instanceBasicSetting.SchemaVersion, currentSchemaVersion) {
|
||||||
slog.Error("cannot downgrade schema version",
|
slog.Error("cannot downgrade schema version",
|
||||||
slog.String("databaseVersion", workspaceBasicSetting.SchemaVersion),
|
slog.String("databaseVersion", instanceBasicSetting.SchemaVersion),
|
||||||
slog.String("currentVersion", currentSchemaVersion),
|
slog.String("currentVersion", currentSchemaVersion),
|
||||||
)
|
)
|
||||||
return errors.Errorf("cannot downgrade schema version from %s to %s", workspaceBasicSetting.SchemaVersion, currentSchemaVersion)
|
return errors.Errorf("cannot downgrade schema version from %s to %s", instanceBasicSetting.SchemaVersion, currentSchemaVersion)
|
||||||
}
|
}
|
||||||
// Apply migrations if needed (including when schema version is empty)
|
// Apply migrations if needed (including when schema version is empty)
|
||||||
if isVersionEmpty(workspaceBasicSetting.SchemaVersion) || version.IsVersionGreaterThan(currentSchemaVersion, workspaceBasicSetting.SchemaVersion) {
|
if isVersionEmpty(instanceBasicSetting.SchemaVersion) || version.IsVersionGreaterThan(currentSchemaVersion, instanceBasicSetting.SchemaVersion) {
|
||||||
if err := s.applyMigrations(ctx, workspaceBasicSetting.SchemaVersion, currentSchemaVersion); err != nil {
|
if err := s.applyMigrations(ctx, instanceBasicSetting.SchemaVersion, currentSchemaVersion); err != nil {
|
||||||
return errors.Wrap(err, "failed to apply migrations")
|
return errors.Wrap(err, "failed to apply migrations")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -363,19 +363,19 @@ func (*Store) execute(ctx context.Context, tx *sql.Tx, stmt string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateCurrentSchemaVersion updates the current schema version in the workspace basic setting.
|
// updateCurrentSchemaVersion updates the current schema version in the instance basic setting.
|
||||||
// It retrieves the workspace basic setting, updates the schema version, and upserts the setting back to the database.
|
// It retrieves the instance basic setting, updates the schema version, and upserts the setting back to the database.
|
||||||
func (s *Store) updateCurrentSchemaVersion(ctx context.Context, schemaVersion string) error {
|
func (s *Store) updateCurrentSchemaVersion(ctx context.Context, schemaVersion string) error {
|
||||||
workspaceBasicSetting, err := s.GetWorkspaceBasicSetting(ctx)
|
instanceBasicSetting, err := s.GetInstanceBasicSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get workspace basic setting")
|
return errors.Wrap(err, "failed to get instance basic setting")
|
||||||
}
|
}
|
||||||
workspaceBasicSetting.SchemaVersion = schemaVersion
|
instanceBasicSetting.SchemaVersion = schemaVersion
|
||||||
if _, err := s.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{
|
if _, err := s.UpsertInstanceSetting(ctx, &storepb.InstanceSetting{
|
||||||
Key: storepb.WorkspaceSettingKey_BASIC,
|
Key: storepb.InstanceSettingKey_BASIC,
|
||||||
Value: &storepb.WorkspaceSetting_BasicSetting{BasicSetting: workspaceBasicSetting},
|
Value: &storepb.InstanceSetting_BasicSetting{BasicSetting: instanceBasicSetting},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return errors.Wrap(err, "failed to upsert workspace setting")
|
return errors.Wrap(err, "failed to upsert instance setting")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -383,7 +383,7 @@ func (s *Store) updateCurrentSchemaVersion(ctx context.Context, schemaVersion st
|
||||||
// normalizeMigrationHistoryList normalizes the migration history list.
|
// normalizeMigrationHistoryList normalizes the migration history list.
|
||||||
// It checks the existing migration history and updates it to the latest schema version if necessary.
|
// It checks the existing migration history and updates it to the latest schema version if necessary.
|
||||||
// NOTE: This is a transition function for backward compatibility with the deprecated migration_history table.
|
// NOTE: This is a transition function for backward compatibility with the deprecated migration_history table.
|
||||||
// This ensures that old installations (< 0.22) have their migration_history normalized before migrating to workspace_setting.
|
// This ensures that old installations (< 0.22) have their migration_history normalized before migrating to system_setting.
|
||||||
func (s *Store) normalizeMigrationHistoryList(ctx context.Context) error {
|
func (s *Store) normalizeMigrationHistoryList(ctx context.Context) error {
|
||||||
migrationHistoryList, err := s.driver.FindMigrationHistoryList(ctx, &FindMigrationHistory{})
|
migrationHistoryList, err := s.driver.FindMigrationHistoryList(ctx, &FindMigrationHistory{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -435,11 +435,11 @@ func (s *Store) normalizeMigrationHistoryList(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// migrateSchemaVersionToSetting migrates the schema version from the migration history to the workspace basic setting.
|
// migrateSchemaVersionToSetting migrates the schema version from the migration history to the instance basic setting.
|
||||||
// It retrieves the migration history, sorts the versions, and updates the workspace basic setting if necessary.
|
// It retrieves the migration history, sorts the versions, and updates the instance basic setting if necessary.
|
||||||
// NOTE: This is a transition function for backward compatibility with the deprecated migration_history table.
|
// NOTE: This is a transition function for backward compatibility with the deprecated migration_history table.
|
||||||
// The migration_history table is deprecated in favor of storing schema version in workspace_setting.
|
// The migration_history table is deprecated in favor of storing schema version in system_setting.
|
||||||
// This handles upgrades from old installations that only have migration_history but no workspace_setting.
|
// This handles upgrades from old installations that only have migration_history but no system_setting.
|
||||||
func (s *Store) migrateSchemaVersionToSetting(ctx context.Context) error {
|
func (s *Store) migrateSchemaVersionToSetting(ctx context.Context) error {
|
||||||
migrationHistoryList, err := s.driver.FindMigrationHistoryList(ctx, &FindMigrationHistory{})
|
migrationHistoryList, err := s.driver.FindMigrationHistoryList(ctx, &FindMigrationHistory{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -455,16 +455,16 @@ func (s *Store) migrateSchemaVersionToSetting(ctx context.Context) error {
|
||||||
sort.Sort(version.SortVersion(versions))
|
sort.Sort(version.SortVersion(versions))
|
||||||
latestVersion := versions[len(versions)-1]
|
latestVersion := versions[len(versions)-1]
|
||||||
|
|
||||||
workspaceBasicSetting, err := s.GetWorkspaceBasicSetting(ctx)
|
instanceBasicSetting, err := s.GetInstanceBasicSetting(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get workspace basic setting")
|
return errors.Wrap(err, "failed to get instance basic setting")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If workspace_setting has no schema version (empty), or migration_history has a newer version, update workspace_setting.
|
// If instance_setting has no schema version (empty), or migration_history has a newer version, update instance_setting.
|
||||||
// This handles upgrades from old installations where schema version was only tracked in migration_history.
|
// This handles upgrades from old installations where schema version was only tracked in migration_history.
|
||||||
if isVersionEmpty(workspaceBasicSetting.SchemaVersion) || version.IsVersionGreaterThan(latestVersion, workspaceBasicSetting.SchemaVersion) {
|
if isVersionEmpty(instanceBasicSetting.SchemaVersion) || version.IsVersionGreaterThan(latestVersion, instanceBasicSetting.SchemaVersion) {
|
||||||
slog.Info("migrating schema version from migration_history to workspace_setting",
|
slog.Info("migrating schema version from migration_history to instance_setting",
|
||||||
slog.String("from", workspaceBasicSetting.SchemaVersion),
|
slog.String("from", instanceBasicSetting.SchemaVersion),
|
||||||
slog.String("to", latestVersion),
|
slog.String("to", latestVersion),
|
||||||
)
|
)
|
||||||
if err := s.updateCurrentSchemaVersion(ctx, latestVersion); err != nil {
|
if err := s.updateCurrentSchemaVersion(ctx, latestVersion); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ type Store struct {
|
||||||
cacheConfig cache.Config
|
cacheConfig cache.Config
|
||||||
|
|
||||||
// Caches
|
// Caches
|
||||||
workspaceSettingCache *cache.Cache // cache for workspace settings
|
instanceSettingCache *cache.Cache // cache for instance settings
|
||||||
userCache *cache.Cache // cache for users
|
userCache *cache.Cache // cache for users
|
||||||
userSettingCache *cache.Cache // cache for user settings
|
userSettingCache *cache.Cache // cache for user settings
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +35,7 @@ func New(driver Driver, profile *profile.Profile) *Store {
|
||||||
driver: driver,
|
driver: driver,
|
||||||
profile: profile,
|
profile: profile,
|
||||||
cacheConfig: cacheConfig,
|
cacheConfig: cacheConfig,
|
||||||
workspaceSettingCache: cache.New(cacheConfig),
|
instanceSettingCache: cache.New(cacheConfig),
|
||||||
userCache: cache.New(cacheConfig),
|
userCache: cache.New(cacheConfig),
|
||||||
userSettingCache: cache.New(cacheConfig),
|
userSettingCache: cache.New(cacheConfig),
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +49,7 @@ func (s *Store) GetDriver() Driver {
|
||||||
|
|
||||||
func (s *Store) Close() error {
|
func (s *Store) Close() error {
|
||||||
// Stop all cache cleanup goroutines
|
// Stop all cache cleanup goroutines
|
||||||
s.workspaceSettingCache.Close()
|
s.instanceSettingCache.Close()
|
||||||
s.userCache.Close()
|
s.userCache.Close()
|
||||||
s.userSettingCache.Close()
|
s.userSettingCache.Close()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
storepb "github.com/usememos/memos/proto/gen/store"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInstanceSettingV1Store(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ts := NewTestingStore(ctx, t)
|
||||||
|
instanceSetting, err := ts.UpsertInstanceSetting(ctx, &storepb.InstanceSetting{
|
||||||
|
Key: storepb.InstanceSettingKey_GENERAL,
|
||||||
|
Value: &storepb.InstanceSetting_GeneralSetting{
|
||||||
|
GeneralSetting: &storepb.InstanceGeneralSetting{
|
||||||
|
AdditionalScript: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
setting, err := ts.GetInstanceSetting(ctx, &store.FindInstanceSetting{
|
||||||
|
Name: storepb.InstanceSettingKey_GENERAL.String(),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, instanceSetting, setting)
|
||||||
|
ts.Close()
|
||||||
|
}
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
storepb "github.com/usememos/memos/proto/gen/store"
|
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestWorkspaceSettingV1Store(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
ts := NewTestingStore(ctx, t)
|
|
||||||
workspaceSetting, err := ts.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{
|
|
||||||
Key: storepb.WorkspaceSettingKey_GENERAL,
|
|
||||||
Value: &storepb.WorkspaceSetting_GeneralSetting{
|
|
||||||
GeneralSetting: &storepb.WorkspaceGeneralSetting{
|
|
||||||
AdditionalScript: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
setting, err := ts.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
|
|
||||||
Name: storepb.WorkspaceSettingKey_GENERAL.String(),
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, workspaceSetting, setting)
|
|
||||||
ts.Close()
|
|
||||||
}
|
|
||||||
|
|
@ -1,245 +0,0 @@
|
||||||
package store
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"google.golang.org/protobuf/encoding/protojson"
|
|
||||||
|
|
||||||
storepb "github.com/usememos/memos/proto/gen/store"
|
|
||||||
)
|
|
||||||
|
|
||||||
type WorkspaceSetting struct {
|
|
||||||
Name string
|
|
||||||
Value string
|
|
||||||
Description string
|
|
||||||
}
|
|
||||||
|
|
||||||
type FindWorkspaceSetting struct {
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteWorkspaceSetting struct {
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) UpsertWorkspaceSetting(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) {
|
|
||||||
workspaceSettingRaw := &WorkspaceSetting{
|
|
||||||
Name: upsert.Key.String(),
|
|
||||||
}
|
|
||||||
var valueBytes []byte
|
|
||||||
var err error
|
|
||||||
if upsert.Key == storepb.WorkspaceSettingKey_BASIC {
|
|
||||||
valueBytes, err = protojson.Marshal(upsert.GetBasicSetting())
|
|
||||||
} else if upsert.Key == storepb.WorkspaceSettingKey_GENERAL {
|
|
||||||
valueBytes, err = protojson.Marshal(upsert.GetGeneralSetting())
|
|
||||||
} else if upsert.Key == storepb.WorkspaceSettingKey_STORAGE {
|
|
||||||
valueBytes, err = protojson.Marshal(upsert.GetStorageSetting())
|
|
||||||
} else if upsert.Key == storepb.WorkspaceSettingKey_MEMO_RELATED {
|
|
||||||
valueBytes, err = protojson.Marshal(upsert.GetMemoRelatedSetting())
|
|
||||||
} else {
|
|
||||||
return nil, errors.Errorf("unsupported workspace setting key: %v", upsert.Key)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to marshal workspace setting value")
|
|
||||||
}
|
|
||||||
valueString := string(valueBytes)
|
|
||||||
workspaceSettingRaw.Value = valueString
|
|
||||||
workspaceSettingRaw, err = s.driver.UpsertWorkspaceSetting(ctx, workspaceSettingRaw)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "Failed to upsert workspace setting")
|
|
||||||
}
|
|
||||||
workspaceSetting, err := convertWorkspaceSettingFromRaw(workspaceSettingRaw)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "Failed to convert workspace setting")
|
|
||||||
}
|
|
||||||
s.workspaceSettingCache.Set(ctx, workspaceSetting.Key.String(), workspaceSetting)
|
|
||||||
return workspaceSetting, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSetting) ([]*storepb.WorkspaceSetting, error) {
|
|
||||||
list, err := s.driver.ListWorkspaceSettings(ctx, find)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
workspaceSettings := []*storepb.WorkspaceSetting{}
|
|
||||||
for _, workspaceSettingRaw := range list {
|
|
||||||
workspaceSetting, err := convertWorkspaceSettingFromRaw(workspaceSettingRaw)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "Failed to convert workspace setting")
|
|
||||||
}
|
|
||||||
if workspaceSetting == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s.workspaceSettingCache.Set(ctx, workspaceSetting.Key.String(), workspaceSetting)
|
|
||||||
workspaceSettings = append(workspaceSettings, workspaceSetting)
|
|
||||||
}
|
|
||||||
return workspaceSettings, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) GetWorkspaceSetting(ctx context.Context, find *FindWorkspaceSetting) (*storepb.WorkspaceSetting, error) {
|
|
||||||
if cache, ok := s.workspaceSettingCache.Get(ctx, find.Name); ok {
|
|
||||||
workspaceSetting, ok := cache.(*storepb.WorkspaceSetting)
|
|
||||||
if ok {
|
|
||||||
return workspaceSetting, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list, err := s.ListWorkspaceSettings(ctx, find)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(list) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if len(list) > 1 {
|
|
||||||
return nil, errors.Errorf("found multiple workspace settings with key %s", find.Name)
|
|
||||||
}
|
|
||||||
return list[0], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) GetWorkspaceBasicSetting(ctx context.Context) (*storepb.WorkspaceBasicSetting, error) {
|
|
||||||
workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
|
|
||||||
Name: storepb.WorkspaceSettingKey_BASIC.String(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to get workspace basic setting")
|
|
||||||
}
|
|
||||||
|
|
||||||
workspaceBasicSetting := &storepb.WorkspaceBasicSetting{}
|
|
||||||
if workspaceSetting != nil {
|
|
||||||
workspaceBasicSetting = workspaceSetting.GetBasicSetting()
|
|
||||||
}
|
|
||||||
s.workspaceSettingCache.Set(ctx, storepb.WorkspaceSettingKey_BASIC.String(), &storepb.WorkspaceSetting{
|
|
||||||
Key: storepb.WorkspaceSettingKey_BASIC,
|
|
||||||
Value: &storepb.WorkspaceSetting_BasicSetting{BasicSetting: workspaceBasicSetting},
|
|
||||||
})
|
|
||||||
return workspaceBasicSetting, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) GetWorkspaceGeneralSetting(ctx context.Context) (*storepb.WorkspaceGeneralSetting, error) {
|
|
||||||
workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
|
|
||||||
Name: storepb.WorkspaceSettingKey_GENERAL.String(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to get workspace general setting")
|
|
||||||
}
|
|
||||||
|
|
||||||
workspaceGeneralSetting := &storepb.WorkspaceGeneralSetting{}
|
|
||||||
if workspaceSetting != nil {
|
|
||||||
workspaceGeneralSetting = workspaceSetting.GetGeneralSetting()
|
|
||||||
}
|
|
||||||
s.workspaceSettingCache.Set(ctx, storepb.WorkspaceSettingKey_GENERAL.String(), &storepb.WorkspaceSetting{
|
|
||||||
Key: storepb.WorkspaceSettingKey_GENERAL,
|
|
||||||
Value: &storepb.WorkspaceSetting_GeneralSetting{GeneralSetting: workspaceGeneralSetting},
|
|
||||||
})
|
|
||||||
return workspaceGeneralSetting, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultContentLengthLimit is the default limit of content length in bytes. 8KB.
|
|
||||||
const DefaultContentLengthLimit = 8 * 1024
|
|
||||||
|
|
||||||
// DefaultReactions is the default reactions for memo related setting.
|
|
||||||
var DefaultReactions = []string{"👍", "👎", "❤️", "🎉", "😄", "😕", "😢", "😡"}
|
|
||||||
|
|
||||||
// DefaultNsfwTags is the default tags that mark content as NSFW for blurring.
|
|
||||||
var DefaultNsfwTags = []string{"nsfw"}
|
|
||||||
|
|
||||||
func (s *Store) GetWorkspaceMemoRelatedSetting(ctx context.Context) (*storepb.WorkspaceMemoRelatedSetting, error) {
|
|
||||||
workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
|
|
||||||
Name: storepb.WorkspaceSettingKey_MEMO_RELATED.String(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to get workspace general setting")
|
|
||||||
}
|
|
||||||
|
|
||||||
workspaceMemoRelatedSetting := &storepb.WorkspaceMemoRelatedSetting{}
|
|
||||||
if workspaceSetting != nil {
|
|
||||||
workspaceMemoRelatedSetting = workspaceSetting.GetMemoRelatedSetting()
|
|
||||||
}
|
|
||||||
if workspaceMemoRelatedSetting.ContentLengthLimit < DefaultContentLengthLimit {
|
|
||||||
workspaceMemoRelatedSetting.ContentLengthLimit = DefaultContentLengthLimit
|
|
||||||
}
|
|
||||||
if len(workspaceMemoRelatedSetting.Reactions) == 0 {
|
|
||||||
workspaceMemoRelatedSetting.Reactions = append(workspaceMemoRelatedSetting.Reactions, DefaultReactions...)
|
|
||||||
}
|
|
||||||
if len(workspaceMemoRelatedSetting.NsfwTags) == 0 {
|
|
||||||
workspaceMemoRelatedSetting.NsfwTags = append(workspaceMemoRelatedSetting.NsfwTags, DefaultNsfwTags...)
|
|
||||||
}
|
|
||||||
s.workspaceSettingCache.Set(ctx, storepb.WorkspaceSettingKey_MEMO_RELATED.String(), &storepb.WorkspaceSetting{
|
|
||||||
Key: storepb.WorkspaceSettingKey_MEMO_RELATED,
|
|
||||||
Value: &storepb.WorkspaceSetting_MemoRelatedSetting{MemoRelatedSetting: workspaceMemoRelatedSetting},
|
|
||||||
})
|
|
||||||
return workspaceMemoRelatedSetting, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultWorkspaceStorageType = storepb.WorkspaceStorageSetting_DATABASE
|
|
||||||
defaultWorkspaceUploadSizeLimitMb = 30
|
|
||||||
defaultWorkspaceFilepathTemplate = "assets/{timestamp}_{filename}"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Store) GetWorkspaceStorageSetting(ctx context.Context) (*storepb.WorkspaceStorageSetting, error) {
|
|
||||||
workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
|
|
||||||
Name: storepb.WorkspaceSettingKey_STORAGE.String(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to get workspace storage setting")
|
|
||||||
}
|
|
||||||
|
|
||||||
workspaceStorageSetting := &storepb.WorkspaceStorageSetting{}
|
|
||||||
if workspaceSetting != nil {
|
|
||||||
workspaceStorageSetting = workspaceSetting.GetStorageSetting()
|
|
||||||
}
|
|
||||||
if workspaceStorageSetting.StorageType == storepb.WorkspaceStorageSetting_STORAGE_TYPE_UNSPECIFIED {
|
|
||||||
workspaceStorageSetting.StorageType = defaultWorkspaceStorageType
|
|
||||||
}
|
|
||||||
if workspaceStorageSetting.UploadSizeLimitMb == 0 {
|
|
||||||
workspaceStorageSetting.UploadSizeLimitMb = defaultWorkspaceUploadSizeLimitMb
|
|
||||||
}
|
|
||||||
if workspaceStorageSetting.FilepathTemplate == "" {
|
|
||||||
workspaceStorageSetting.FilepathTemplate = defaultWorkspaceFilepathTemplate
|
|
||||||
}
|
|
||||||
s.workspaceSettingCache.Set(ctx, storepb.WorkspaceSettingKey_STORAGE.String(), &storepb.WorkspaceSetting{
|
|
||||||
Key: storepb.WorkspaceSettingKey_STORAGE,
|
|
||||||
Value: &storepb.WorkspaceSetting_StorageSetting{StorageSetting: workspaceStorageSetting},
|
|
||||||
})
|
|
||||||
return workspaceStorageSetting, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertWorkspaceSettingFromRaw(workspaceSettingRaw *WorkspaceSetting) (*storepb.WorkspaceSetting, error) {
|
|
||||||
workspaceSetting := &storepb.WorkspaceSetting{
|
|
||||||
Key: storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[workspaceSettingRaw.Name]),
|
|
||||||
}
|
|
||||||
switch workspaceSettingRaw.Name {
|
|
||||||
case storepb.WorkspaceSettingKey_BASIC.String():
|
|
||||||
basicSetting := &storepb.WorkspaceBasicSetting{}
|
|
||||||
if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), basicSetting); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_BasicSetting{BasicSetting: basicSetting}
|
|
||||||
case storepb.WorkspaceSettingKey_GENERAL.String():
|
|
||||||
generalSetting := &storepb.WorkspaceGeneralSetting{}
|
|
||||||
if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), generalSetting); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_GeneralSetting{GeneralSetting: generalSetting}
|
|
||||||
case storepb.WorkspaceSettingKey_STORAGE.String():
|
|
||||||
storageSetting := &storepb.WorkspaceStorageSetting{}
|
|
||||||
if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), storageSetting); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_StorageSetting{StorageSetting: storageSetting}
|
|
||||||
case storepb.WorkspaceSettingKey_MEMO_RELATED.String():
|
|
||||||
memoRelatedSetting := &storepb.WorkspaceMemoRelatedSetting{}
|
|
||||||
if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), memoRelatedSetting); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_MemoRelatedSetting{MemoRelatedSetting: memoRelatedSetting}
|
|
||||||
default:
|
|
||||||
// Skip unsupported workspace setting key.
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return workspaceSetting, nil
|
|
||||||
}
|
|
||||||
|
|
@ -3,16 +3,16 @@ import { useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
import useNavigateTo from "./hooks/useNavigateTo";
|
import useNavigateTo from "./hooks/useNavigateTo";
|
||||||
import { userStore, workspaceStore } from "./store";
|
import { userStore, instanceStore } from "./store";
|
||||||
import { cleanupExpiredOAuthState } from "./utils/oauth";
|
import { cleanupExpiredOAuthState } from "./utils/oauth";
|
||||||
import { loadTheme } from "./utils/theme";
|
import { loadTheme } from "./utils/theme";
|
||||||
|
|
||||||
const App = observer(() => {
|
const App = observer(() => {
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
const navigateTo = useNavigateTo();
|
const navigateTo = useNavigateTo();
|
||||||
const workspaceProfile = workspaceStore.state.profile;
|
const instanceProfile = instanceStore.state.profile;
|
||||||
const userGeneralSetting = userStore.state.userGeneralSetting;
|
const userGeneralSetting = userStore.state.userGeneralSetting;
|
||||||
const workspaceGeneralSetting = workspaceStore.state.generalSetting;
|
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||||
|
|
||||||
// Clean up expired OAuth states on app initialization
|
// Clean up expired OAuth states on app initialization
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -21,41 +21,41 @@ const App = observer(() => {
|
||||||
|
|
||||||
// Redirect to sign up page if no instance owner.
|
// Redirect to sign up page if no instance owner.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!workspaceProfile.owner) {
|
if (!instanceProfile.owner) {
|
||||||
navigateTo("/auth/signup");
|
navigateTo("/auth/signup");
|
||||||
}
|
}
|
||||||
}, [workspaceProfile.owner]);
|
}, [instanceProfile.owner]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (workspaceGeneralSetting.additionalStyle) {
|
if (instanceGeneralSetting.additionalStyle) {
|
||||||
const styleEl = document.createElement("style");
|
const styleEl = document.createElement("style");
|
||||||
styleEl.innerHTML = workspaceGeneralSetting.additionalStyle;
|
styleEl.innerHTML = instanceGeneralSetting.additionalStyle;
|
||||||
styleEl.setAttribute("type", "text/css");
|
styleEl.setAttribute("type", "text/css");
|
||||||
document.body.insertAdjacentElement("beforeend", styleEl);
|
document.body.insertAdjacentElement("beforeend", styleEl);
|
||||||
}
|
}
|
||||||
}, [workspaceGeneralSetting.additionalStyle]);
|
}, [instanceGeneralSetting.additionalStyle]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (workspaceGeneralSetting.additionalScript) {
|
if (instanceGeneralSetting.additionalScript) {
|
||||||
const scriptEl = document.createElement("script");
|
const scriptEl = document.createElement("script");
|
||||||
scriptEl.innerHTML = workspaceGeneralSetting.additionalScript;
|
scriptEl.innerHTML = instanceGeneralSetting.additionalScript;
|
||||||
document.head.appendChild(scriptEl);
|
document.head.appendChild(scriptEl);
|
||||||
}
|
}
|
||||||
}, [workspaceGeneralSetting.additionalScript]);
|
}, [instanceGeneralSetting.additionalScript]);
|
||||||
|
|
||||||
// Dynamic update metadata with customized profile.
|
// Dynamic update metadata with customized profile.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!workspaceGeneralSetting.customProfile) {
|
if (!instanceGeneralSetting.customProfile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.title = workspaceGeneralSetting.customProfile.title;
|
document.title = instanceGeneralSetting.customProfile.title;
|
||||||
const link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
|
const link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
|
||||||
link.href = workspaceGeneralSetting.customProfile.logoUrl || "/logo.webp";
|
link.href = instanceGeneralSetting.customProfile.logoUrl || "/logo.webp";
|
||||||
}, [workspaceGeneralSetting.customProfile]);
|
}, [instanceGeneralSetting.customProfile]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentLocale = workspaceStore.state.locale;
|
const currentLocale = instanceStore.state.locale;
|
||||||
// This will trigger re-rendering of the whole app.
|
// This will trigger re-rendering of the whole app.
|
||||||
i18n.changeLanguage(currentLocale);
|
i18n.changeLanguage(currentLocale);
|
||||||
document.documentElement.setAttribute("lang", currentLocale);
|
document.documentElement.setAttribute("lang", currentLocale);
|
||||||
|
|
@ -64,26 +64,26 @@ const App = observer(() => {
|
||||||
} else {
|
} else {
|
||||||
document.documentElement.setAttribute("dir", "ltr");
|
document.documentElement.setAttribute("dir", "ltr");
|
||||||
}
|
}
|
||||||
}, [workspaceStore.state.locale]);
|
}, [instanceStore.state.locale]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!userGeneralSetting) {
|
if (!userGeneralSetting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceStore.state.setPartial({
|
instanceStore.state.setPartial({
|
||||||
locale: userGeneralSetting.locale || workspaceStore.state.locale,
|
locale: userGeneralSetting.locale || instanceStore.state.locale,
|
||||||
theme: userGeneralSetting.theme || workspaceStore.state.theme,
|
theme: userGeneralSetting.theme || instanceStore.state.theme,
|
||||||
});
|
});
|
||||||
}, [userGeneralSetting?.locale, userGeneralSetting?.theme]);
|
}, [userGeneralSetting?.locale, userGeneralSetting?.theme]);
|
||||||
|
|
||||||
// Load theme when workspace theme changes or user setting changes
|
// Load theme when instance theme changes or user setting changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentTheme = userGeneralSetting?.theme || workspaceStore.state.theme;
|
const currentTheme = userGeneralSetting?.theme || instanceStore.state.theme;
|
||||||
if (currentTheme) {
|
if (currentTheme) {
|
||||||
loadTheme(currentTheme);
|
loadTheme(currentTheme);
|
||||||
}
|
}
|
||||||
}, [userGeneralSetting?.theme, workspaceStore.state.theme]);
|
}, [userGeneralSetting?.theme, instanceStore.state.theme]);
|
||||||
|
|
||||||
return <Outlet />;
|
return <Outlet />;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import dayjs from "dayjs";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { memo, useMemo } from "react";
|
import { memo, useMemo } from "react";
|
||||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import type { ActivityCalendarProps } from "@/types/statistics";
|
import type { ActivityCalendarProps } from "@/types/statistics";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
import { CalendarCell } from "./CalendarCell";
|
import { CalendarCell } from "./CalendarCell";
|
||||||
|
|
@ -12,7 +12,7 @@ export const ActivityCalendar = memo(
|
||||||
observer((props: ActivityCalendarProps) => {
|
observer((props: ActivityCalendarProps) => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const { month, selectedDate, data, onClick } = props;
|
const { month, selectedDate, data, onClick } = props;
|
||||||
const weekStartDayOffset = workspaceStore.state.generalSetting.weekStartDayOffset;
|
const weekStartDayOffset = instanceStore.state.generalSetting.weekStartDayOffset;
|
||||||
|
|
||||||
const today = useMemo(() => dayjs().format("YYYY-MM-DD"), []);
|
const today = useMemo(() => dayjs().format("YYYY-MM-DD"), []);
|
||||||
const selectedDateFormatted = useMemo(() => dayjs(selectedDate).format("YYYY-MM-DD"), [selectedDate]);
|
const selectedDateFormatted = useMemo(() => dayjs(selectedDate).format("YYYY-MM-DD"), [selectedDate]);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import LocaleSelect from "./LocaleSelect";
|
import LocaleSelect from "./LocaleSelect";
|
||||||
import ThemeSelect from "./ThemeSelect";
|
import ThemeSelect from "./ThemeSelect";
|
||||||
|
|
||||||
|
|
@ -11,8 +11,8 @@ interface Props {
|
||||||
const AuthFooter = observer(({ className }: Props) => {
|
const AuthFooter = observer(({ className }: Props) => {
|
||||||
return (
|
return (
|
||||||
<div className={cn("mt-4 flex flex-row items-center justify-center w-full gap-2", className)}>
|
<div className={cn("mt-4 flex flex-row items-center justify-center w-full gap-2", className)}>
|
||||||
<LocaleSelect value={workspaceStore.state.locale} onChange={(locale) => workspaceStore.state.setPartial({ locale })} />
|
<LocaleSelect value={instanceStore.state.locale} onChange={(locale) => instanceStore.state.setPartial({ locale })} />
|
||||||
<ThemeSelect value={workspaceStore.state.theme} onValueChange={(theme) => workspaceStore.state.setPartial({ theme })} />
|
<ThemeSelect value={instanceStore.state.theme} onValueChange={(theme) => instanceStore.state.setPartial({ theme })} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import { useLocation } from "react-router-dom";
|
||||||
import ConfirmDialog from "@/components/ConfirmDialog";
|
import ConfirmDialog from "@/components/ConfirmDialog";
|
||||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||||
import { memoStore, userStore } from "@/store";
|
import { memoStore, userStore } from "@/store";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { State } from "@/types/proto/api/v1/common";
|
import { State } from "@/types/proto/api/v1/common";
|
||||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
@ -119,7 +119,7 @@ const MemoActionMenu = observer((props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCopyLink = () => {
|
const handleCopyLink = () => {
|
||||||
let host = workspaceStore.state.profile.instanceUrl;
|
let host = instanceStore.state.profile.instanceUrl;
|
||||||
if (host === "") {
|
if (host === "") {
|
||||||
host = window.location.origin;
|
host = window.location.origin;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import { isValidUrl } from "@/helpers/utils";
|
||||||
import useAsyncEffect from "@/hooks/useAsyncEffect";
|
import useAsyncEffect from "@/hooks/useAsyncEffect";
|
||||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { memoStore, attachmentStore, userStore, workspaceStore } from "@/store";
|
import { memoStore, attachmentStore, userStore, instanceStore } from "@/store";
|
||||||
import { extractMemoIdFromName } from "@/store/common";
|
import { extractMemoIdFromName } from "@/store/common";
|
||||||
import { Attachment } from "@/types/proto/api/v1/attachment_service";
|
import { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||||
import { Location, Memo, MemoRelation, MemoRelation_Type, Visibility } from "@/types/proto/api/v1/memo_service";
|
import { Location, Memo, MemoRelation, MemoRelation_Type, Visibility } from "@/types/proto/api/v1/memo_service";
|
||||||
|
|
@ -81,7 +81,7 @@ const MemoEditor = observer((props: Props) => {
|
||||||
relation.memo?.name === memoName && relation.relatedMemo?.name !== memoName && relation.type === MemoRelation_Type.REFERENCE,
|
relation.memo?.name === memoName && relation.relatedMemo?.name !== memoName && relation.type === MemoRelation_Type.REFERENCE,
|
||||||
)
|
)
|
||||||
: state.relationList.filter((relation) => relation.type === MemoRelation_Type.REFERENCE);
|
: state.relationList.filter((relation) => relation.type === MemoRelation_Type.REFERENCE);
|
||||||
const workspaceMemoRelatedSetting = workspaceStore.state.memoRelatedSetting;
|
const instanceMemoRelatedSetting = instanceStore.state.memoRelatedSetting;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
editorRef.current?.setContent(contentCache || "");
|
editorRef.current?.setContent(contentCache || "");
|
||||||
|
|
@ -95,7 +95,7 @@ const MemoEditor = observer((props: Props) => {
|
||||||
|
|
||||||
useAsyncEffect(async () => {
|
useAsyncEffect(async () => {
|
||||||
let visibility = convertVisibilityFromString(userGeneralSetting?.memoVisibility || "PRIVATE");
|
let visibility = convertVisibilityFromString(userGeneralSetting?.memoVisibility || "PRIVATE");
|
||||||
if (workspaceMemoRelatedSetting.disallowPublicVisibility && visibility === Visibility.PUBLIC) {
|
if (instanceMemoRelatedSetting.disallowPublicVisibility && visibility === Visibility.PUBLIC) {
|
||||||
visibility = Visibility.PROTECTED;
|
visibility = Visibility.PROTECTED;
|
||||||
}
|
}
|
||||||
if (parentMemoName) {
|
if (parentMemoName) {
|
||||||
|
|
@ -106,7 +106,7 @@ const MemoEditor = observer((props: Props) => {
|
||||||
...prevState,
|
...prevState,
|
||||||
memoVisibility: convertVisibilityFromString(visibility),
|
memoVisibility: convertVisibilityFromString(visibility),
|
||||||
}));
|
}));
|
||||||
}, [parentMemoName, userGeneralSetting?.memoVisibility, workspaceMemoRelatedSetting.disallowPublicVisibility]);
|
}, [parentMemoName, userGeneralSetting?.memoVisibility, instanceMemoRelatedSetting.disallowPublicVisibility]);
|
||||||
|
|
||||||
useAsyncEffect(async () => {
|
useAsyncEffect(async () => {
|
||||||
if (!memoName) {
|
if (!memoName) {
|
||||||
|
|
@ -156,7 +156,7 @@ const MemoEditor = observer((props: Props) => {
|
||||||
handleSaveBtnClick();
|
handleSaveBtnClick();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!workspaceMemoRelatedSetting.disableMarkdownShortcuts) {
|
if (!instanceMemoRelatedSetting.disableMarkdownShortcuts) {
|
||||||
handleEditorKeydownWithMarkdownShortcuts(event, editorRef.current);
|
handleEditorKeydownWithMarkdownShortcuts(event, editorRef.current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import useAsyncEffect from "@/hooks/useAsyncEffect";
|
||||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { memoStore, userStore, workspaceStore } from "@/store";
|
import { memoStore, userStore, instanceStore } from "@/store";
|
||||||
import { State } from "@/types/proto/api/v1/common";
|
import { State } from "@/types/proto/api/v1/common";
|
||||||
import { Memo, MemoRelation_Type, Visibility } from "@/types/proto/api/v1/memo_service";
|
import { Memo, MemoRelation_Type, Visibility } from "@/types/proto/api/v1/memo_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
@ -52,7 +52,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
urls: [],
|
urls: [],
|
||||||
index: 0,
|
index: 0,
|
||||||
});
|
});
|
||||||
const workspaceMemoRelatedSetting = workspaceStore.state.memoRelatedSetting;
|
const instanceMemoRelatedSetting = instanceStore.state.memoRelatedSetting;
|
||||||
const referencedMemos = memo.relations.filter((relation) => relation.type === MemoRelation_Type.REFERENCE);
|
const referencedMemos = memo.relations.filter((relation) => relation.type === MemoRelation_Type.REFERENCE);
|
||||||
const commentAmount = memo.relations.filter(
|
const commentAmount = memo.relations.filter(
|
||||||
(relation) => relation.type === MemoRelation_Type.COMMENT && relation.relatedMemo?.name === memo.name,
|
(relation) => relation.type === MemoRelation_Type.COMMENT && relation.relatedMemo?.name === memo.name,
|
||||||
|
|
@ -63,8 +63,8 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
const isInMemoDetailPage = location.pathname.startsWith(`/${memo.name}`);
|
const isInMemoDetailPage = location.pathname.startsWith(`/${memo.name}`);
|
||||||
const parentPage = props.parentPage || location.pathname;
|
const parentPage = props.parentPage || location.pathname;
|
||||||
const nsfw =
|
const nsfw =
|
||||||
workspaceMemoRelatedSetting.enableBlurNsfwContent &&
|
instanceMemoRelatedSetting.enableBlurNsfwContent &&
|
||||||
memo.tags?.some((tag) => workspaceMemoRelatedSetting.nsfwTags.some((nsfwTag) => tag === nsfwTag || tag.startsWith(`${nsfwTag}/`)));
|
memo.tags?.some((tag) => instanceMemoRelatedSetting.nsfwTags.some((nsfwTag) => tag === nsfwTag || tag.startsWith(`${nsfwTag}/`)));
|
||||||
|
|
||||||
// Initial related data: creator.
|
// Initial related data: creator.
|
||||||
useAsyncEffect(async () => {
|
useAsyncEffect(async () => {
|
||||||
|
|
@ -103,7 +103,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workspaceMemoRelatedSetting.enableDoubleClickEdit) {
|
if (instanceMemoRelatedSetting.enableDoubleClickEdit) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setShowEditor(true);
|
setShowEditor(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import UserAvatar from "./UserAvatar";
|
import UserAvatar from "./UserAvatar";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
@ -10,9 +10,9 @@ interface Props {
|
||||||
|
|
||||||
const MemosLogo = observer((props: Props) => {
|
const MemosLogo = observer((props: Props) => {
|
||||||
const { collapsed } = props;
|
const { collapsed } = props;
|
||||||
const workspaceGeneralSetting = workspaceStore.state.generalSetting;
|
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||||
const title = workspaceGeneralSetting.customProfile?.title || "Memos";
|
const title = instanceGeneralSetting.customProfile?.title || "Memos";
|
||||||
const avatarUrl = workspaceGeneralSetting.customProfile?.logoUrl || "/full-logo.webp";
|
const avatarUrl = instanceGeneralSetting.customProfile?.logoUrl || "/full-logo.webp";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("relative w-full h-auto shrink-0", props.className)}>
|
<div className={cn("relative w-full h-auto shrink-0", props.className)}>
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@ import { useEffect, useState } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import Navigation from "./Navigation";
|
import Navigation from "./Navigation";
|
||||||
import UserAvatar from "./UserAvatar";
|
import UserAvatar from "./UserAvatar";
|
||||||
|
|
||||||
const NavigationDrawer = observer(() => {
|
const NavigationDrawer = observer(() => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const workspaceGeneralSetting = workspaceStore.state.generalSetting;
|
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||||
const title = workspaceGeneralSetting.customProfile?.title || "Memos";
|
const title = instanceGeneralSetting.customProfile?.title || "Memos";
|
||||||
const avatarUrl = workspaceGeneralSetting.customProfile?.logoUrl || "/full-logo.webp";
|
const avatarUrl = instanceGeneralSetting.customProfile?.logoUrl || "/full-logo.webp";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { Input } from "@/components/ui/input";
|
||||||
import { authServiceClient } from "@/grpcweb";
|
import { authServiceClient } from "@/grpcweb";
|
||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { initialUserStore } from "@/store/user";
|
import { initialUserStore } from "@/store/user";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
||||||
|
|
@ -16,8 +16,8 @@ const PasswordSignInForm = observer(() => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const navigateTo = useNavigateTo();
|
const navigateTo = useNavigateTo();
|
||||||
const actionBtnLoadingState = useLoading(false);
|
const actionBtnLoadingState = useLoading(false);
|
||||||
const [username, setUsername] = useState(workspaceStore.state.profile.mode === "demo" ? "demo" : "");
|
const [username, setUsername] = useState(instanceStore.state.profile.mode === "demo" ? "demo" : "");
|
||||||
const [password, setPassword] = useState(workspaceStore.state.profile.mode === "demo" ? "secret" : "");
|
const [password, setPassword] = useState(instanceStore.state.profile.mode === "demo" ? "secret" : "");
|
||||||
|
|
||||||
const handleUsernameInputChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleUsernameInputChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const text = e.target.value as string;
|
const text = e.target.value as string;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import useClickAway from "react-use/lib/useClickAway";
|
||||||
import { memoServiceClient } from "@/grpcweb";
|
import { memoServiceClient } from "@/grpcweb";
|
||||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { memoStore, workspaceStore } from "@/store";
|
import { memoStore, instanceStore } from "@/store";
|
||||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ const ReactionSelector = observer((props: Props) => {
|
||||||
const currentUser = useCurrentUser();
|
const currentUser = useCurrentUser();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const workspaceMemoRelatedSetting = workspaceStore.state.memoRelatedSetting;
|
const instanceMemoRelatedSetting = instanceStore.state.memoRelatedSetting;
|
||||||
|
|
||||||
useClickAway(containerRef, () => {
|
useClickAway(containerRef, () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
|
@ -76,7 +76,7 @@ const ReactionSelector = observer((props: Props) => {
|
||||||
<PopoverContent align="center" className="max-w-[90vw] sm:max-w-md">
|
<PopoverContent align="center" className="max-w-[90vw] sm:max-w-md">
|
||||||
<div ref={containerRef}>
|
<div ref={containerRef}>
|
||||||
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-1 max-h-64 overflow-y-auto">
|
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-1 max-h-64 overflow-y-auto">
|
||||||
{workspaceMemoRelatedSetting.reactions.map((reactionType) => {
|
{instanceMemoRelatedSetting.reactions.map((reactionType) => {
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
key={reactionType}
|
key={reactionType}
|
||||||
|
|
|
||||||
|
|
@ -9,35 +9,35 @@ import { Switch } from "@/components/ui/switch";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { identityProviderServiceClient } from "@/grpcweb";
|
import { identityProviderServiceClient } from "@/grpcweb";
|
||||||
import useDialog from "@/hooks/useDialog";
|
import useDialog from "@/hooks/useDialog";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { workspaceSettingNamePrefix } from "@/store/common";
|
import { instanceSettingNamePrefix } from "@/store/common";
|
||||||
import { IdentityProvider } from "@/types/proto/api/v1/idp_service";
|
import { IdentityProvider } from "@/types/proto/api/v1/idp_service";
|
||||||
import { WorkspaceSetting_GeneralSetting, WorkspaceSetting_Key } from "@/types/proto/api/v1/workspace_service";
|
import { InstanceSetting_GeneralSetting, InstanceSetting_Key } from "@/types/proto/api/v1/instance_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
import ThemeSelect from "../ThemeSelect";
|
import ThemeSelect from "../ThemeSelect";
|
||||||
import UpdateCustomizedProfileDialog from "../UpdateCustomizedProfileDialog";
|
import UpdateCustomizedProfileDialog from "../UpdateCustomizedProfileDialog";
|
||||||
|
|
||||||
const WorkspaceSection = observer(() => {
|
const InstanceSection = observer(() => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const customizeDialog = useDialog();
|
const customizeDialog = useDialog();
|
||||||
const originalSetting = WorkspaceSetting_GeneralSetting.fromPartial(
|
const originalSetting = InstanceSetting_GeneralSetting.fromPartial(
|
||||||
workspaceStore.getWorkspaceSettingByKey(WorkspaceSetting_Key.GENERAL)?.generalSetting || {},
|
instanceStore.getInstanceSettingByKey(InstanceSetting_Key.GENERAL)?.generalSetting || {},
|
||||||
);
|
);
|
||||||
const [workspaceGeneralSetting, setWorkspaceGeneralSetting] = useState<WorkspaceSetting_GeneralSetting>(originalSetting);
|
const [instanceGeneralSetting, setInstanceGeneralSetting] = useState<InstanceSetting_GeneralSetting>(originalSetting);
|
||||||
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
|
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setWorkspaceGeneralSetting({ ...workspaceGeneralSetting, customProfile: originalSetting.customProfile });
|
setInstanceGeneralSetting({ ...instanceGeneralSetting, customProfile: originalSetting.customProfile });
|
||||||
}, [workspaceStore.getWorkspaceSettingByKey(WorkspaceSetting_Key.GENERAL)]);
|
}, [instanceStore.getInstanceSettingByKey(InstanceSetting_Key.GENERAL)]);
|
||||||
|
|
||||||
const handleUpdateCustomizedProfileButtonClick = () => {
|
const handleUpdateCustomizedProfileButtonClick = () => {
|
||||||
customizeDialog.open();
|
customizeDialog.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
const updatePartialSetting = (partial: Partial<WorkspaceSetting_GeneralSetting>) => {
|
const updatePartialSetting = (partial: Partial<InstanceSetting_GeneralSetting>) => {
|
||||||
setWorkspaceGeneralSetting(
|
setInstanceGeneralSetting(
|
||||||
WorkspaceSetting_GeneralSetting.fromPartial({
|
InstanceSetting_GeneralSetting.fromPartial({
|
||||||
...workspaceGeneralSetting,
|
...instanceGeneralSetting,
|
||||||
...partial,
|
...partial,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
@ -45,9 +45,9 @@ const WorkspaceSection = observer(() => {
|
||||||
|
|
||||||
const handleSaveGeneralSetting = async () => {
|
const handleSaveGeneralSetting = async () => {
|
||||||
try {
|
try {
|
||||||
await workspaceStore.upsertWorkspaceSetting({
|
await instanceStore.upsertInstanceSetting({
|
||||||
name: `${workspaceSettingNamePrefix}${WorkspaceSetting_Key.GENERAL}`,
|
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
|
||||||
generalSetting: workspaceGeneralSetting,
|
generalSetting: instanceGeneralSetting,
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
toast.error(error.details);
|
toast.error(error.details);
|
||||||
|
|
@ -72,7 +72,7 @@ const WorkspaceSection = observer(() => {
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
{t("setting.system-section.server-name")}:{" "}
|
{t("setting.system-section.server-name")}:{" "}
|
||||||
<span className="font-mono font-bold">{workspaceGeneralSetting.customProfile?.title || "Memos"}</span>
|
<span className="font-mono font-bold">{instanceGeneralSetting.customProfile?.title || "Memos"}</span>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="outline" onClick={handleUpdateCustomizedProfileButtonClick}>
|
<Button variant="outline" onClick={handleUpdateCustomizedProfileButtonClick}>
|
||||||
{t("common.edit")}
|
{t("common.edit")}
|
||||||
|
|
@ -83,7 +83,7 @@ const WorkspaceSection = observer(() => {
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span>Theme</span>
|
<span>Theme</span>
|
||||||
<ThemeSelect
|
<ThemeSelect
|
||||||
value={workspaceGeneralSetting.theme || "default"}
|
value={instanceGeneralSetting.theme || "default"}
|
||||||
onValueChange={(value: string) => updatePartialSetting({ theme: value })}
|
onValueChange={(value: string) => updatePartialSetting({ theme: value })}
|
||||||
className="min-w-fit"
|
className="min-w-fit"
|
||||||
/>
|
/>
|
||||||
|
|
@ -95,7 +95,7 @@ const WorkspaceSection = observer(() => {
|
||||||
className="font-mono w-full"
|
className="font-mono w-full"
|
||||||
rows={3}
|
rows={3}
|
||||||
placeholder={t("setting.system-section.additional-style-placeholder")}
|
placeholder={t("setting.system-section.additional-style-placeholder")}
|
||||||
value={workspaceGeneralSetting.additionalStyle}
|
value={instanceGeneralSetting.additionalStyle}
|
||||||
onChange={(event) => updatePartialSetting({ additionalStyle: event.target.value })}
|
onChange={(event) => updatePartialSetting({ additionalStyle: event.target.value })}
|
||||||
/>
|
/>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
|
|
@ -105,46 +105,46 @@ const WorkspaceSection = observer(() => {
|
||||||
className="font-mono w-full"
|
className="font-mono w-full"
|
||||||
rows={3}
|
rows={3}
|
||||||
placeholder={t("setting.system-section.additional-script-placeholder")}
|
placeholder={t("setting.system-section.additional-script-placeholder")}
|
||||||
value={workspaceGeneralSetting.additionalScript}
|
value={instanceGeneralSetting.additionalScript}
|
||||||
onChange={(event) => updatePartialSetting({ additionalScript: event.target.value })}
|
onChange={(event) => updatePartialSetting({ additionalScript: event.target.value })}
|
||||||
/>
|
/>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span>{t("setting.workspace-section.disallow-user-registration")}</span>
|
<span>{t("setting.instance-section.disallow-user-registration")}</span>
|
||||||
<Switch
|
<Switch
|
||||||
disabled={workspaceStore.state.profile.mode === "demo"}
|
disabled={instanceStore.state.profile.mode === "demo"}
|
||||||
checked={workspaceGeneralSetting.disallowUserRegistration}
|
checked={instanceGeneralSetting.disallowUserRegistration}
|
||||||
onCheckedChange={(checked) => updatePartialSetting({ disallowUserRegistration: checked })}
|
onCheckedChange={(checked) => updatePartialSetting({ disallowUserRegistration: checked })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span>{t("setting.workspace-section.disallow-password-auth")}</span>
|
<span>{t("setting.instance-section.disallow-password-auth")}</span>
|
||||||
<Switch
|
<Switch
|
||||||
disabled={
|
disabled={
|
||||||
workspaceStore.state.profile.mode === "demo" ||
|
instanceStore.state.profile.mode === "demo" ||
|
||||||
(identityProviderList.length === 0 && !workspaceGeneralSetting.disallowPasswordAuth)
|
(identityProviderList.length === 0 && !instanceGeneralSetting.disallowPasswordAuth)
|
||||||
}
|
}
|
||||||
checked={workspaceGeneralSetting.disallowPasswordAuth}
|
checked={instanceGeneralSetting.disallowPasswordAuth}
|
||||||
onCheckedChange={(checked) => updatePartialSetting({ disallowPasswordAuth: checked })}
|
onCheckedChange={(checked) => updatePartialSetting({ disallowPasswordAuth: checked })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span>{t("setting.workspace-section.disallow-change-username")}</span>
|
<span>{t("setting.instance-section.disallow-change-username")}</span>
|
||||||
<Switch
|
<Switch
|
||||||
checked={workspaceGeneralSetting.disallowChangeUsername}
|
checked={instanceGeneralSetting.disallowChangeUsername}
|
||||||
onCheckedChange={(checked) => updatePartialSetting({ disallowChangeUsername: checked })}
|
onCheckedChange={(checked) => updatePartialSetting({ disallowChangeUsername: checked })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span>{t("setting.workspace-section.disallow-change-nickname")}</span>
|
<span>{t("setting.instance-section.disallow-change-nickname")}</span>
|
||||||
<Switch
|
<Switch
|
||||||
checked={workspaceGeneralSetting.disallowChangeNickname}
|
checked={instanceGeneralSetting.disallowChangeNickname}
|
||||||
onCheckedChange={(checked) => updatePartialSetting({ disallowChangeNickname: checked })}
|
onCheckedChange={(checked) => updatePartialSetting({ disallowChangeNickname: checked })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="truncate">{t("setting.workspace-section.week-start-day")}</span>
|
<span className="truncate">{t("setting.instance-section.week-start-day")}</span>
|
||||||
<Select
|
<Select
|
||||||
value={workspaceGeneralSetting.weekStartDayOffset.toString()}
|
value={instanceGeneralSetting.weekStartDayOffset.toString()}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
updatePartialSetting({ weekStartDayOffset: parseInt(value) || 0 });
|
updatePartialSetting({ weekStartDayOffset: parseInt(value) || 0 });
|
||||||
}}
|
}}
|
||||||
|
|
@ -153,14 +153,14 @@ const WorkspaceSection = observer(() => {
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="-1">{t("setting.workspace-section.saturday")}</SelectItem>
|
<SelectItem value="-1">{t("setting.instance-section.saturday")}</SelectItem>
|
||||||
<SelectItem value="0">{t("setting.workspace-section.sunday")}</SelectItem>
|
<SelectItem value="0">{t("setting.instance-section.sunday")}</SelectItem>
|
||||||
<SelectItem value="1">{t("setting.workspace-section.monday")}</SelectItem>
|
<SelectItem value="1">{t("setting.instance-section.monday")}</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 w-full flex justify-end">
|
<div className="mt-2 w-full flex justify-end">
|
||||||
<Button disabled={isEqual(workspaceGeneralSetting, originalSetting)} onClick={handleSaveGeneralSetting}>
|
<Button disabled={isEqual(instanceGeneralSetting, originalSetting)} onClick={handleSaveGeneralSetting}>
|
||||||
{t("common.save")}
|
{t("common.save")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -169,7 +169,7 @@ const WorkspaceSection = observer(() => {
|
||||||
open={customizeDialog.isOpen}
|
open={customizeDialog.isOpen}
|
||||||
onOpenChange={customizeDialog.setOpen}
|
onOpenChange={customizeDialog.setOpen}
|
||||||
onSuccess={() => {
|
onSuccess={() => {
|
||||||
// Refresh workspace settings if needed
|
// Refresh instance settings if needed
|
||||||
toast.success("Profile updated successfully!");
|
toast.success("Profile updated successfully!");
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -177,4 +177,4 @@ const WorkspaceSection = observer(() => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default WorkspaceSection;
|
export default InstanceSection;
|
||||||
|
|
@ -7,24 +7,24 @@ import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { workspaceSettingNamePrefix } from "@/store/common";
|
import { instanceSettingNamePrefix } from "@/store/common";
|
||||||
import { WorkspaceSetting_MemoRelatedSetting, WorkspaceSetting_Key } from "@/types/proto/api/v1/workspace_service";
|
import { InstanceSetting_MemoRelatedSetting, InstanceSetting_Key } from "@/types/proto/api/v1/instance_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
||||||
const MemoRelatedSettings = observer(() => {
|
const MemoRelatedSettings = observer(() => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const [originalSetting, setOriginalSetting] = useState<WorkspaceSetting_MemoRelatedSetting>(workspaceStore.state.memoRelatedSetting);
|
const [originalSetting, setOriginalSetting] = useState<InstanceSetting_MemoRelatedSetting>(instanceStore.state.memoRelatedSetting);
|
||||||
const [memoRelatedSetting, setMemoRelatedSetting] = useState<WorkspaceSetting_MemoRelatedSetting>(originalSetting);
|
const [memoRelatedSetting, setMemoRelatedSetting] = useState<InstanceSetting_MemoRelatedSetting>(originalSetting);
|
||||||
const [editingReaction, setEditingReaction] = useState<string>("");
|
const [editingReaction, setEditingReaction] = useState<string>("");
|
||||||
const [editingNsfwTag, setEditingNsfwTag] = useState<string>("");
|
const [editingNsfwTag, setEditingNsfwTag] = useState<string>("");
|
||||||
|
|
||||||
const updatePartialSetting = (partial: Partial<WorkspaceSetting_MemoRelatedSetting>) => {
|
const updatePartialSetting = (partial: Partial<InstanceSetting_MemoRelatedSetting>) => {
|
||||||
const newWorkspaceMemoRelatedSetting = WorkspaceSetting_MemoRelatedSetting.fromPartial({
|
const newInstanceMemoRelatedSetting = InstanceSetting_MemoRelatedSetting.fromPartial({
|
||||||
...memoRelatedSetting,
|
...memoRelatedSetting,
|
||||||
...partial,
|
...partial,
|
||||||
});
|
});
|
||||||
setMemoRelatedSetting(newWorkspaceMemoRelatedSetting);
|
setMemoRelatedSetting(newInstanceMemoRelatedSetting);
|
||||||
};
|
};
|
||||||
|
|
||||||
const upsertReaction = () => {
|
const upsertReaction = () => {
|
||||||
|
|
@ -52,8 +52,8 @@ const MemoRelatedSettings = observer(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await workspaceStore.upsertWorkspaceSetting({
|
await instanceStore.upsertInstanceSetting({
|
||||||
name: `${workspaceSettingNamePrefix}${WorkspaceSetting_Key.MEMO_RELATED}`,
|
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.MEMO_RELATED}`,
|
||||||
memoRelatedSetting,
|
memoRelatedSetting,
|
||||||
});
|
});
|
||||||
setOriginalSetting(memoRelatedSetting);
|
setOriginalSetting(memoRelatedSetting);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
import { userStore, workspaceStore } from "@/store";
|
import { userStore, instanceStore } from "@/store";
|
||||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||||
import { UserSetting_GeneralSetting } from "@/types/proto/api/v1/user_service";
|
import { UserSetting_GeneralSetting } from "@/types/proto/api/v1/user_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
@ -16,8 +16,8 @@ const PreferencesSection = observer(() => {
|
||||||
const generalSetting = userStore.state.userGeneralSetting;
|
const generalSetting = userStore.state.userGeneralSetting;
|
||||||
|
|
||||||
const handleLocaleSelectChange = async (locale: Locale) => {
|
const handleLocaleSelectChange = async (locale: Locale) => {
|
||||||
// Update workspace store immediately for instant UI feedback
|
// Update instance store immediately for instant UI feedback
|
||||||
workspaceStore.state.setPartial({ locale });
|
instanceStore.state.setPartial({ locale });
|
||||||
// Persist to user settings
|
// Persist to user settings
|
||||||
await userStore.updateUserGeneralSetting({ locale }, ["locale"]);
|
await userStore.updateUserGeneralSetting({ locale }, ["locale"]);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,87 +9,83 @@ import { Label } from "@/components/ui/label";
|
||||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { workspaceSettingNamePrefix } from "@/store/common";
|
import { instanceSettingNamePrefix } from "@/store/common";
|
||||||
import {
|
import {
|
||||||
WorkspaceSetting_Key,
|
InstanceSetting_Key,
|
||||||
WorkspaceSetting_StorageSetting,
|
InstanceSetting_StorageSetting,
|
||||||
WorkspaceSetting_StorageSetting_S3Config,
|
InstanceSetting_StorageSetting_S3Config,
|
||||||
WorkspaceSetting_StorageSetting_StorageType,
|
InstanceSetting_StorageSetting_StorageType,
|
||||||
} from "@/types/proto/api/v1/workspace_service";
|
} from "@/types/proto/api/v1/instance_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
||||||
const StorageSection = observer(() => {
|
const StorageSection = observer(() => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const [workspaceStorageSetting, setWorkspaceStorageSetting] = useState<WorkspaceSetting_StorageSetting>(
|
const [instanceStorageSetting, setInstanceStorageSetting] = useState<InstanceSetting_StorageSetting>(
|
||||||
WorkspaceSetting_StorageSetting.fromPartial(
|
InstanceSetting_StorageSetting.fromPartial(instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)?.storageSetting || {}),
|
||||||
workspaceStore.getWorkspaceSettingByKey(WorkspaceSetting_Key.STORAGE)?.storageSetting || {},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setWorkspaceStorageSetting(
|
setInstanceStorageSetting(
|
||||||
WorkspaceSetting_StorageSetting.fromPartial(
|
InstanceSetting_StorageSetting.fromPartial(instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)?.storageSetting || {}),
|
||||||
workspaceStore.getWorkspaceSettingByKey(WorkspaceSetting_Key.STORAGE)?.storageSetting || {},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}, [workspaceStore.getWorkspaceSettingByKey(WorkspaceSetting_Key.STORAGE)]);
|
}, [instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)]);
|
||||||
|
|
||||||
const allowSaveStorageSetting = useMemo(() => {
|
const allowSaveStorageSetting = useMemo(() => {
|
||||||
if (workspaceStorageSetting.uploadSizeLimitMb <= 0) {
|
if (instanceStorageSetting.uploadSizeLimitMb <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const origin = WorkspaceSetting_StorageSetting.fromPartial(
|
const origin = InstanceSetting_StorageSetting.fromPartial(
|
||||||
workspaceStore.getWorkspaceSettingByKey(WorkspaceSetting_Key.STORAGE)?.storageSetting || {},
|
instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)?.storageSetting || {},
|
||||||
);
|
);
|
||||||
if (workspaceStorageSetting.storageType === WorkspaceSetting_StorageSetting_StorageType.LOCAL) {
|
if (instanceStorageSetting.storageType === InstanceSetting_StorageSetting_StorageType.LOCAL) {
|
||||||
if (workspaceStorageSetting.filepathTemplate.length === 0) {
|
if (instanceStorageSetting.filepathTemplate.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (workspaceStorageSetting.storageType === WorkspaceSetting_StorageSetting_StorageType.S3) {
|
} else if (instanceStorageSetting.storageType === InstanceSetting_StorageSetting_StorageType.S3) {
|
||||||
if (
|
if (
|
||||||
workspaceStorageSetting.s3Config?.accessKeyId.length === 0 ||
|
instanceStorageSetting.s3Config?.accessKeyId.length === 0 ||
|
||||||
workspaceStorageSetting.s3Config?.accessKeySecret.length === 0 ||
|
instanceStorageSetting.s3Config?.accessKeySecret.length === 0 ||
|
||||||
workspaceStorageSetting.s3Config?.endpoint.length === 0 ||
|
instanceStorageSetting.s3Config?.endpoint.length === 0 ||
|
||||||
workspaceStorageSetting.s3Config?.region.length === 0 ||
|
instanceStorageSetting.s3Config?.region.length === 0 ||
|
||||||
workspaceStorageSetting.s3Config?.bucket.length === 0
|
instanceStorageSetting.s3Config?.bucket.length === 0
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return !isEqual(origin, workspaceStorageSetting);
|
return !isEqual(origin, instanceStorageSetting);
|
||||||
}, [workspaceStorageSetting, workspaceStore.state]);
|
}, [instanceStorageSetting, instanceStore.state]);
|
||||||
|
|
||||||
const handleMaxUploadSizeChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
|
const handleMaxUploadSizeChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
|
||||||
let num = parseInt(event.target.value);
|
let num = parseInt(event.target.value);
|
||||||
if (Number.isNaN(num)) {
|
if (Number.isNaN(num)) {
|
||||||
num = 0;
|
num = 0;
|
||||||
}
|
}
|
||||||
const update: WorkspaceSetting_StorageSetting = {
|
const update: InstanceSetting_StorageSetting = {
|
||||||
...workspaceStorageSetting,
|
...instanceStorageSetting,
|
||||||
uploadSizeLimitMb: num,
|
uploadSizeLimitMb: num,
|
||||||
};
|
};
|
||||||
setWorkspaceStorageSetting(update);
|
setInstanceStorageSetting(update);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFilepathTemplateChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
|
const handleFilepathTemplateChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
|
||||||
const update: WorkspaceSetting_StorageSetting = {
|
const update: InstanceSetting_StorageSetting = {
|
||||||
...workspaceStorageSetting,
|
...instanceStorageSetting,
|
||||||
filepathTemplate: event.target.value,
|
filepathTemplate: event.target.value,
|
||||||
};
|
};
|
||||||
setWorkspaceStorageSetting(update);
|
setInstanceStorageSetting(update);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePartialS3ConfigChanged = async (s3Config: Partial<WorkspaceSetting_StorageSetting_S3Config>) => {
|
const handlePartialS3ConfigChanged = async (s3Config: Partial<InstanceSetting_StorageSetting_S3Config>) => {
|
||||||
const update: WorkspaceSetting_StorageSetting = {
|
const update: InstanceSetting_StorageSetting = {
|
||||||
...workspaceStorageSetting,
|
...instanceStorageSetting,
|
||||||
s3Config: WorkspaceSetting_StorageSetting_S3Config.fromPartial({
|
s3Config: InstanceSetting_StorageSetting_S3Config.fromPartial({
|
||||||
...workspaceStorageSetting.s3Config,
|
...instanceStorageSetting.s3Config,
|
||||||
...s3Config,
|
...s3Config,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
setWorkspaceStorageSetting(update);
|
setInstanceStorageSetting(update);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleS3ConfigAccessKeyIdChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
|
const handleS3ConfigAccessKeyIdChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
|
||||||
|
|
@ -118,18 +114,18 @@ const StorageSection = observer(() => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleStorageTypeChanged = async (storageType: WorkspaceSetting_StorageSetting_StorageType) => {
|
const handleStorageTypeChanged = async (storageType: InstanceSetting_StorageSetting_StorageType) => {
|
||||||
const update: WorkspaceSetting_StorageSetting = {
|
const update: InstanceSetting_StorageSetting = {
|
||||||
...workspaceStorageSetting,
|
...instanceStorageSetting,
|
||||||
storageType: storageType,
|
storageType: storageType,
|
||||||
};
|
};
|
||||||
setWorkspaceStorageSetting(update);
|
setInstanceStorageSetting(update);
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveWorkspaceStorageSetting = async () => {
|
const saveInstanceStorageSetting = async () => {
|
||||||
await workspaceStore.upsertWorkspaceSetting({
|
await instanceStore.upsertInstanceSetting({
|
||||||
name: `${workspaceSettingNamePrefix}${WorkspaceSetting_Key.STORAGE}`,
|
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.STORAGE}`,
|
||||||
storageSetting: workspaceStorageSetting,
|
storageSetting: instanceStorageSetting,
|
||||||
});
|
});
|
||||||
toast.success("Updated");
|
toast.success("Updated");
|
||||||
};
|
};
|
||||||
|
|
@ -138,22 +134,22 @@ const StorageSection = observer(() => {
|
||||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||||
<div className="font-medium text-muted-foreground">{t("setting.storage-section.current-storage")}</div>
|
<div className="font-medium text-muted-foreground">{t("setting.storage-section.current-storage")}</div>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
value={workspaceStorageSetting.storageType}
|
value={instanceStorageSetting.storageType}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
handleStorageTypeChanged(value as WorkspaceSetting_StorageSetting_StorageType);
|
handleStorageTypeChanged(value as InstanceSetting_StorageSetting_StorageType);
|
||||||
}}
|
}}
|
||||||
className="flex flex-row gap-4"
|
className="flex flex-row gap-4"
|
||||||
>
|
>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<RadioGroupItem value={WorkspaceSetting_StorageSetting_StorageType.DATABASE} id="database" />
|
<RadioGroupItem value={InstanceSetting_StorageSetting_StorageType.DATABASE} id="database" />
|
||||||
<Label htmlFor="database">{t("setting.storage-section.type-database")}</Label>
|
<Label htmlFor="database">{t("setting.storage-section.type-database")}</Label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<RadioGroupItem value={WorkspaceSetting_StorageSetting_StorageType.LOCAL} id="local" />
|
<RadioGroupItem value={InstanceSetting_StorageSetting_StorageType.LOCAL} id="local" />
|
||||||
<Label htmlFor="local">{t("setting.storage-section.type-local")}</Label>
|
<Label htmlFor="local">{t("setting.storage-section.type-local")}</Label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<RadioGroupItem value={WorkspaceSetting_StorageSetting_StorageType.S3} id="s3" />
|
<RadioGroupItem value={InstanceSetting_StorageSetting_StorageType.S3} id="s3" />
|
||||||
<Label htmlFor="s3">S3</Label>
|
<Label htmlFor="s3">S3</Label>
|
||||||
</div>
|
</div>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
@ -171,26 +167,26 @@ const StorageSection = observer(() => {
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</div>
|
</div>
|
||||||
<Input className="w-16 font-mono" value={workspaceStorageSetting.uploadSizeLimitMb} onChange={handleMaxUploadSizeChanged} />
|
<Input className="w-16 font-mono" value={instanceStorageSetting.uploadSizeLimitMb} onChange={handleMaxUploadSizeChanged} />
|
||||||
</div>
|
</div>
|
||||||
{workspaceStorageSetting.storageType !== WorkspaceSetting_StorageSetting_StorageType.DATABASE && (
|
{instanceStorageSetting.storageType !== InstanceSetting_StorageSetting_StorageType.DATABASE && (
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-muted-foreground mr-1">{t("setting.storage-section.filepath-template")}</span>
|
<span className="text-muted-foreground mr-1">{t("setting.storage-section.filepath-template")}</span>
|
||||||
<Input
|
<Input
|
||||||
className="w-64"
|
className="w-64"
|
||||||
value={workspaceStorageSetting.filepathTemplate}
|
value={instanceStorageSetting.filepathTemplate}
|
||||||
placeholder="assets/{timestamp}_{filename}"
|
placeholder="assets/{timestamp}_{filename}"
|
||||||
onChange={handleFilepathTemplateChanged}
|
onChange={handleFilepathTemplateChanged}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{workspaceStorageSetting.storageType === WorkspaceSetting_StorageSetting_StorageType.S3 && (
|
{instanceStorageSetting.storageType === InstanceSetting_StorageSetting_StorageType.S3 && (
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-muted-foreground mr-1">Access key id</span>
|
<span className="text-muted-foreground mr-1">Access key id</span>
|
||||||
<Input
|
<Input
|
||||||
className="w-64"
|
className="w-64"
|
||||||
value={workspaceStorageSetting.s3Config?.accessKeyId}
|
value={instanceStorageSetting.s3Config?.accessKeyId}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
onChange={handleS3ConfigAccessKeyIdChanged}
|
onChange={handleS3ConfigAccessKeyIdChanged}
|
||||||
/>
|
/>
|
||||||
|
|
@ -199,7 +195,7 @@ const StorageSection = observer(() => {
|
||||||
<span className="text-muted-foreground mr-1">Access key secret</span>
|
<span className="text-muted-foreground mr-1">Access key secret</span>
|
||||||
<Input
|
<Input
|
||||||
className="w-64"
|
className="w-64"
|
||||||
value={workspaceStorageSetting.s3Config?.accessKeySecret}
|
value={instanceStorageSetting.s3Config?.accessKeySecret}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
onChange={handleS3ConfigAccessKeySecretChanged}
|
onChange={handleS3ConfigAccessKeySecretChanged}
|
||||||
/>
|
/>
|
||||||
|
|
@ -208,40 +204,30 @@ const StorageSection = observer(() => {
|
||||||
<span className="text-muted-foreground mr-1">Endpoint</span>
|
<span className="text-muted-foreground mr-1">Endpoint</span>
|
||||||
<Input
|
<Input
|
||||||
className="w-64"
|
className="w-64"
|
||||||
value={workspaceStorageSetting.s3Config?.endpoint}
|
value={instanceStorageSetting.s3Config?.endpoint}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
onChange={handleS3ConfigEndpointChanged}
|
onChange={handleS3ConfigEndpointChanged}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-muted-foreground mr-1">Region</span>
|
<span className="text-muted-foreground mr-1">Region</span>
|
||||||
<Input
|
<Input className="w-64" value={instanceStorageSetting.s3Config?.region} placeholder="" onChange={handleS3ConfigRegionChanged} />
|
||||||
className="w-64"
|
|
||||||
value={workspaceStorageSetting.s3Config?.region}
|
|
||||||
placeholder=""
|
|
||||||
onChange={handleS3ConfigRegionChanged}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-muted-foreground mr-1">Bucket</span>
|
<span className="text-muted-foreground mr-1">Bucket</span>
|
||||||
<Input
|
<Input className="w-64" value={instanceStorageSetting.s3Config?.bucket} placeholder="" onChange={handleS3ConfigBucketChanged} />
|
||||||
className="w-64"
|
|
||||||
value={workspaceStorageSetting.s3Config?.bucket}
|
|
||||||
placeholder=""
|
|
||||||
onChange={handleS3ConfigBucketChanged}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-muted-foreground mr-1">Use Path Style</span>
|
<span className="text-muted-foreground mr-1">Use Path Style</span>
|
||||||
<Switch
|
<Switch
|
||||||
checked={workspaceStorageSetting.s3Config?.usePathStyle}
|
checked={instanceStorageSetting.s3Config?.usePathStyle}
|
||||||
onCheckedChange={(checked) => handleS3ConfigUsePathStyleChanged({ target: { checked } } as any)}
|
onCheckedChange={(checked) => handleS3ConfigUsePathStyleChanged({ target: { checked } } as any)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
<Button disabled={!allowSaveStorageSetting} onClick={saveWorkspaceStorageSetting}>
|
<Button disabled={!allowSaveStorageSetting} onClick={saveInstanceStorageSetting}>
|
||||||
{t("common.save")}
|
{t("common.save")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Moon, Palette, Sun, Wallpaper } from "lucide-react";
|
import { Moon, Palette, Sun, Wallpaper } from "lucide-react";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { THEME_OPTIONS } from "@/utils/theme";
|
import { THEME_OPTIONS } from "@/utils/theme";
|
||||||
|
|
||||||
interface ThemeSelectProps {
|
interface ThemeSelectProps {
|
||||||
|
|
@ -17,13 +17,13 @@ const THEME_ICONS: Record<string, JSX.Element> = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const ThemeSelect = ({ value, onValueChange, className }: ThemeSelectProps = {}) => {
|
const ThemeSelect = ({ value, onValueChange, className }: ThemeSelectProps = {}) => {
|
||||||
const currentTheme = value || workspaceStore.state.theme || "default";
|
const currentTheme = value || instanceStore.state.theme || "default";
|
||||||
|
|
||||||
const handleThemeChange = (newTheme: Theme) => {
|
const handleThemeChange = (newTheme: Theme) => {
|
||||||
if (onValueChange) {
|
if (onValueChange) {
|
||||||
onValueChange(newTheme);
|
onValueChange(newTheme);
|
||||||
} else {
|
} else {
|
||||||
workspaceStore.setTheme(newTheme);
|
instanceStore.setTheme(newTheme);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { Label } from "@/components/ui/label";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { convertFileToBase64 } from "@/helpers/utils";
|
import { convertFileToBase64 } from "@/helpers/utils";
|
||||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||||
import { userStore, workspaceStore } from "@/store";
|
import { userStore, instanceStore } from "@/store";
|
||||||
import { User as UserPb } from "@/types/proto/api/v1/user_service";
|
import { User as UserPb } from "@/types/proto/api/v1/user_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
import UserAvatar from "./UserAvatar";
|
import UserAvatar from "./UserAvatar";
|
||||||
|
|
@ -38,7 +38,7 @@ function UpdateAccountDialog({ open, onOpenChange, onSuccess }: Props) {
|
||||||
email: currentUser.email,
|
email: currentUser.email,
|
||||||
description: currentUser.description,
|
description: currentUser.description,
|
||||||
});
|
});
|
||||||
const workspaceGeneralSetting = workspaceStore.state.generalSetting;
|
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||||
|
|
||||||
const handleCloseBtnClick = () => {
|
const handleCloseBtnClick = () => {
|
||||||
onOpenChange(false);
|
onOpenChange(false);
|
||||||
|
|
@ -179,7 +179,7 @@ function UpdateAccountDialog({ open, onOpenChange, onSuccess }: Props) {
|
||||||
id="username"
|
id="username"
|
||||||
value={state.username}
|
value={state.username}
|
||||||
onChange={handleUsernameChanged}
|
onChange={handleUsernameChanged}
|
||||||
disabled={workspaceGeneralSetting.disallowChangeUsername}
|
disabled={instanceGeneralSetting.disallowChangeUsername}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
|
|
@ -191,7 +191,7 @@ function UpdateAccountDialog({ open, onOpenChange, onSuccess }: Props) {
|
||||||
id="displayName"
|
id="displayName"
|
||||||
value={state.displayName}
|
value={state.displayName}
|
||||||
onChange={handleDisplayNameChanged}
|
onChange={handleDisplayNameChanged}
|
||||||
disabled={workspaceGeneralSetting.disallowChangeNickname}
|
disabled={instanceGeneralSetting.disallowChangeNickname}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, D
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { workspaceSettingNamePrefix } from "@/store/common";
|
import { instanceSettingNamePrefix } from "@/store/common";
|
||||||
import { WorkspaceSetting_GeneralSetting_CustomProfile, WorkspaceSetting_Key } from "@/types/proto/api/v1/workspace_service";
|
import { InstanceSetting_GeneralSetting_CustomProfile, InstanceSetting_Key } from "@/types/proto/api/v1/instance_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
import LocaleSelect from "./LocaleSelect";
|
import LocaleSelect from "./LocaleSelect";
|
||||||
import ThemeSelect from "./ThemeSelect";
|
import ThemeSelect from "./ThemeSelect";
|
||||||
|
|
@ -20,14 +20,14 @@ interface Props {
|
||||||
|
|
||||||
function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props) {
|
function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props) {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const workspaceGeneralSetting = workspaceStore.state.generalSetting;
|
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||||
const [customProfile, setCustomProfile] = useState<WorkspaceSetting_GeneralSetting_CustomProfile>(
|
const [customProfile, setCustomProfile] = useState<InstanceSetting_GeneralSetting_CustomProfile>(
|
||||||
WorkspaceSetting_GeneralSetting_CustomProfile.fromPartial(workspaceGeneralSetting.customProfile || {}),
|
InstanceSetting_GeneralSetting_CustomProfile.fromPartial(instanceGeneralSetting.customProfile || {}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const setPartialState = (partialState: Partial<WorkspaceSetting_GeneralSetting_CustomProfile>) => {
|
const setPartialState = (partialState: Partial<InstanceSetting_GeneralSetting_CustomProfile>) => {
|
||||||
setCustomProfile((state) => ({
|
setCustomProfile((state) => ({
|
||||||
...state,
|
...state,
|
||||||
...partialState,
|
...partialState,
|
||||||
|
|
@ -79,10 +79,10 @@ function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props)
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
await workspaceStore.upsertWorkspaceSetting({
|
await instanceStore.upsertInstanceSetting({
|
||||||
name: `${workspaceSettingNamePrefix}${WorkspaceSetting_Key.GENERAL}`,
|
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
|
||||||
generalSetting: {
|
generalSetting: {
|
||||||
...workspaceGeneralSetting,
|
...instanceGeneralSetting,
|
||||||
customProfile: customProfile,
|
customProfile: customProfile,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -102,7 +102,7 @@ function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props)
|
||||||
<DialogContent className="max-w-2xl">
|
<DialogContent className="max-w-2xl">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>{t("setting.system-section.customize-server.title")}</DialogTitle>
|
<DialogTitle>{t("setting.system-section.customize-server.title")}</DialogTitle>
|
||||||
<DialogDescription>Customize your workspace appearance and settings.</DialogDescription>
|
<DialogDescription>Customize your instance appearance and settings.</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="grid gap-4">
|
<div className="grid gap-4">
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import useNavigateTo from "@/hooks/useNavigateTo";
|
||||||
import { locales } from "@/i18n";
|
import { locales } from "@/i18n";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { Routes } from "@/router";
|
import { Routes } from "@/router";
|
||||||
import { userStore, workspaceStore } from "@/store";
|
import { userStore, instanceStore } from "@/store";
|
||||||
import { getLocaleDisplayName, useTranslate } from "@/utils/i18n";
|
import { getLocaleDisplayName, useTranslate } from "@/utils/i18n";
|
||||||
import { THEME_OPTIONS } from "@/utils/theme";
|
import { THEME_OPTIONS } from "@/utils/theme";
|
||||||
import UserAvatar from "./UserAvatar";
|
import UserAvatar from "./UserAvatar";
|
||||||
|
|
@ -34,8 +34,8 @@ const UserMenu = observer((props: Props) => {
|
||||||
const currentTheme = generalSetting?.theme || "default";
|
const currentTheme = generalSetting?.theme || "default";
|
||||||
|
|
||||||
const handleLocaleChange = async (locale: Locale) => {
|
const handleLocaleChange = async (locale: Locale) => {
|
||||||
// Update workspace store immediately for instant UI feedback
|
// Update instance store immediately for instant UI feedback
|
||||||
workspaceStore.state.setPartial({ locale });
|
instanceStore.state.setPartial({ locale });
|
||||||
// Persist to user settings
|
// Persist to user settings
|
||||||
await userStore.updateUserGeneralSetting({ locale }, ["locale"]);
|
await userStore.updateUserGeneralSetting({ locale }, ["locale"]);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ import { ActivityServiceDefinition } from "./types/proto/api/v1/activity_service
|
||||||
import { AttachmentServiceDefinition } from "./types/proto/api/v1/attachment_service";
|
import { AttachmentServiceDefinition } from "./types/proto/api/v1/attachment_service";
|
||||||
import { AuthServiceDefinition } from "./types/proto/api/v1/auth_service";
|
import { AuthServiceDefinition } from "./types/proto/api/v1/auth_service";
|
||||||
import { IdentityProviderServiceDefinition } from "./types/proto/api/v1/idp_service";
|
import { IdentityProviderServiceDefinition } from "./types/proto/api/v1/idp_service";
|
||||||
|
import { InstanceServiceDefinition } from "./types/proto/api/v1/instance_service";
|
||||||
import { MemoServiceDefinition } from "./types/proto/api/v1/memo_service";
|
import { MemoServiceDefinition } from "./types/proto/api/v1/memo_service";
|
||||||
import { ShortcutServiceDefinition } from "./types/proto/api/v1/shortcut_service";
|
import { ShortcutServiceDefinition } from "./types/proto/api/v1/shortcut_service";
|
||||||
import { UserServiceDefinition } from "./types/proto/api/v1/user_service";
|
import { UserServiceDefinition } from "./types/proto/api/v1/user_service";
|
||||||
import { WorkspaceServiceDefinition } from "./types/proto/api/v1/workspace_service";
|
|
||||||
|
|
||||||
const channel = createChannel(
|
const channel = createChannel(
|
||||||
window.location.origin,
|
window.location.origin,
|
||||||
|
|
@ -17,7 +17,7 @@ const channel = createChannel(
|
||||||
|
|
||||||
const clientFactory = createClientFactory();
|
const clientFactory = createClientFactory();
|
||||||
|
|
||||||
export const workspaceServiceClient = clientFactory.create(WorkspaceServiceDefinition, channel);
|
export const instanceServiceClient = clientFactory.create(InstanceServiceDefinition, channel);
|
||||||
|
|
||||||
export const authServiceClient = clientFactory.create(AuthServiceDefinition, channel);
|
export const authServiceClient = clientFactory.create(AuthServiceDefinition, channel);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { userStore, workspaceStore } from "@/store";
|
import { userStore, instanceStore } from "@/store";
|
||||||
import { extractUserIdFromName } from "@/store/common";
|
import { extractUserIdFromName } from "@/store/common";
|
||||||
import memoFilterStore from "@/store/memoFilter";
|
import memoFilterStore from "@/store/memoFilter";
|
||||||
|
import { InstanceSetting_Key } from "@/types/proto/api/v1/instance_service";
|
||||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||||
import { WorkspaceSetting_Key } from "@/types/proto/api/v1/workspace_service";
|
|
||||||
|
|
||||||
// Helper function to extract shortcut ID from resource name
|
// Helper function to extract shortcut ID from resource name
|
||||||
// Format: users/{user}/shortcuts/{shortcut}
|
// Format: users/{user}/shortcuts/{shortcut}
|
||||||
|
|
@ -121,8 +121,8 @@ export const useMemoFilters = (options: UseMemoFiltersOptions = {}): string | un
|
||||||
} else if (filter.factor === "property.hasCode") {
|
} else if (filter.factor === "property.hasCode") {
|
||||||
conditions.push(`has_code`);
|
conditions.push(`has_code`);
|
||||||
} else if (filter.factor === "displayTime") {
|
} else if (filter.factor === "displayTime") {
|
||||||
// Check workspace setting for display time factor
|
// Check instance setting for display time factor
|
||||||
const displayWithUpdateTime = workspaceStore.getWorkspaceSettingByKey(WorkspaceSetting_Key.MEMO_RELATED).memoRelatedSetting
|
const displayWithUpdateTime = instanceStore.getInstanceSettingByKey(InstanceSetting_Key.MEMO_RELATED).memoRelatedSetting
|
||||||
?.displayWithUpdateTime;
|
?.displayWithUpdateTime;
|
||||||
const factor = displayWithUpdateTime ? "updated_ts" : "created_ts";
|
const factor = displayWithUpdateTime ? "updated_ts" : "created_ts";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import Loading from "@/pages/Loading";
|
import Loading from "@/pages/Loading";
|
||||||
import { Routes } from "@/router";
|
import { Routes } from "@/router";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import memoFilterStore from "@/store/memoFilter";
|
import memoFilterStore from "@/store/memoFilter";
|
||||||
|
|
||||||
const RootLayout = observer(() => {
|
const RootLayout = observer(() => {
|
||||||
|
|
@ -23,7 +23,7 @@ const RootLayout = observer(() => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentUser) {
|
if (!currentUser) {
|
||||||
// If disallowPublicVisibility is enabled, redirect to the login page if the user is not logged in.
|
// If disallowPublicVisibility is enabled, redirect to the login page if the user is not logged in.
|
||||||
if (workspaceStore.state.memoRelatedSetting.disallowPublicVisibility) {
|
if (instanceStore.state.memoRelatedSetting.disallowPublicVisibility) {
|
||||||
window.location.href = Routes.AUTH;
|
window.location.href = Routes.AUTH;
|
||||||
return;
|
return;
|
||||||
} else if (
|
} else if (
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "الرابط"
|
"url": "الرابط"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "عدم السماح بتغيير الاسم المستعار",
|
"disallow-change-nickname": "عدم السماح بتغيير الاسم المستعار",
|
||||||
"disallow-change-username": "عدم السماح بتغيير اسم المستخدم",
|
"disallow-change-username": "عدم السماح بتغيير اسم المستخدم",
|
||||||
"disallow-password-auth": "عدم السماح بالمصادقة بكلمة المرور",
|
"disallow-password-auth": "عدم السماح بالمصادقة بكلمة المرور",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "No permetis canviar el sobrenom",
|
"disallow-change-nickname": "No permetis canviar el sobrenom",
|
||||||
"disallow-change-username": "No permetis canviar el nom d'usuari",
|
"disallow-change-username": "No permetis canviar el nom d'usuari",
|
||||||
"disallow-password-auth": "No permetis autenticació per contrasenya",
|
"disallow-password-auth": "No permetis autenticació per contrasenya",
|
||||||
|
|
|
||||||
|
|
@ -393,7 +393,7 @@
|
||||||
"title": "Webhooky",
|
"title": "Webhooky",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Zakázat změnu přezdívky",
|
"disallow-change-nickname": "Zakázat změnu přezdívky",
|
||||||
"disallow-change-username": "Zakázat změnu uživatelského jména",
|
"disallow-change-username": "Zakázat změnu uživatelského jména",
|
||||||
"disallow-password-auth": "Zakázat ověřování heslem",
|
"disallow-password-auth": "Zakázat ověřování heslem",
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Ändern des Spitznamens verbieten",
|
"disallow-change-nickname": "Ändern des Spitznamens verbieten",
|
||||||
"disallow-change-username": "Ändern des Benutzernamens verbieten",
|
"disallow-change-username": "Ändern des Benutzernamens verbieten",
|
||||||
"disallow-password-auth": "Passwort-Authentifizierung verbieten",
|
"disallow-password-auth": "Passwort-Authentifizierung verbieten",
|
||||||
|
|
|
||||||
|
|
@ -441,7 +441,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Disallow changing nickname",
|
"disallow-change-nickname": "Disallow changing nickname",
|
||||||
"disallow-change-username": "Disallow changing username",
|
"disallow-change-username": "Disallow changing username",
|
||||||
"disallow-password-auth": "Disallow password auth",
|
"disallow-password-auth": "Disallow password auth",
|
||||||
|
|
|
||||||
|
|
@ -406,7 +406,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "No permitir cambiar apodo",
|
"disallow-change-nickname": "No permitir cambiar apodo",
|
||||||
"disallow-change-username": "No permitir cambiar nombre de usuario",
|
"disallow-change-username": "No permitir cambiar nombre de usuario",
|
||||||
"disallow-password-auth": "No permitir autenticación por contraseña",
|
"disallow-password-auth": "No permitir autenticación por contraseña",
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@
|
||||||
"title": "وبهوکها",
|
"title": "وبهوکها",
|
||||||
"url": "آدرس"
|
"url": "آدرس"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "غیرفعالسازی تغییر نام مستعار",
|
"disallow-change-nickname": "غیرفعالسازی تغییر نام مستعار",
|
||||||
"disallow-change-username": "غیرفعالسازی تغییر نام کاربری",
|
"disallow-change-username": "غیرفعالسازی تغییر نام کاربری",
|
||||||
"disallow-password-auth": "غیرفعالسازی احراز هویت با گذرواژه",
|
"disallow-password-auth": "غیرفعالسازی احراز هویت با گذرواژه",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Interdire le changement de surnom",
|
"disallow-change-nickname": "Interdire le changement de surnom",
|
||||||
"disallow-change-username": "Interdire le changement de nom d'utilisateur",
|
"disallow-change-username": "Interdire le changement de nom d'utilisateur",
|
||||||
"disallow-password-auth": "Interdire l'authentification par mot de passe",
|
"disallow-password-auth": "Interdire l'authentification par mot de passe",
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "उपनाम बदलने की अनुमति न दें",
|
"disallow-change-nickname": "उपनाम बदलने की अनुमति न दें",
|
||||||
"disallow-change-username": "उपयोगकर्ता नाम बदलने की अनुमति न दें",
|
"disallow-change-username": "उपयोगकर्ता नाम बदलने की अनुमति न दें",
|
||||||
"disallow-password-auth": "पासवर्ड प्रमाणीकरण की अनुमति न दें",
|
"disallow-password-auth": "पासवर्ड प्रमाणीकरण की अनुमति न दें",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Onemogući promjenu nadimka",
|
"disallow-change-nickname": "Onemogući promjenu nadimka",
|
||||||
"disallow-change-username": "Onemogući promjenu korisničkog imena",
|
"disallow-change-username": "Onemogući promjenu korisničkog imena",
|
||||||
"disallow-password-auth": "Onemogući autentikaciju lozinkom",
|
"disallow-password-auth": "Onemogući autentikaciju lozinkom",
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Becenév módosításának tiltása",
|
"disallow-change-nickname": "Becenév módosításának tiltása",
|
||||||
"disallow-change-username": "Felhasználónév módosításának tiltása",
|
"disallow-change-username": "Felhasználónév módosításának tiltása",
|
||||||
"disallow-password-auth": "Jelszavas hitelesítés tiltása",
|
"disallow-password-auth": "Jelszavas hitelesítés tiltása",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhook",
|
"title": "Webhook",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Larangan mengubah nama panggilan",
|
"disallow-change-nickname": "Larangan mengubah nama panggilan",
|
||||||
"disallow-change-username": "Larangan mengubah nama pengguna",
|
"disallow-change-username": "Larangan mengubah nama pengguna",
|
||||||
"disallow-password-auth": "Larangan autentikasi kata sandi",
|
"disallow-password-auth": "Larangan autentikasi kata sandi",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Non consentire cambio nickname",
|
"disallow-change-nickname": "Non consentire cambio nickname",
|
||||||
"disallow-change-username": "Non consentire cambio nome utente",
|
"disallow-change-username": "Non consentire cambio nome utente",
|
||||||
"disallow-password-auth": "Non consentire autenticazione password",
|
"disallow-password-auth": "Non consentire autenticazione password",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "ニックネーム変更を禁止",
|
"disallow-change-nickname": "ニックネーム変更を禁止",
|
||||||
"disallow-change-username": "ユーザー名変更を禁止",
|
"disallow-change-username": "ユーザー名変更を禁止",
|
||||||
"disallow-password-auth": "パスワード認証を禁止",
|
"disallow-password-auth": "パスワード認証を禁止",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhook-ები",
|
"title": "Webhook-ები",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "მეტსახელის შეცვლის აკრძალვა",
|
"disallow-change-nickname": "მეტსახელის შეცვლის აკრძალვა",
|
||||||
"disallow-change-username": "მომხმარებლის სახელის შეცვლის აკრძალვა",
|
"disallow-change-username": "მომხმარებლის სახელის შეცვლის აკრძალვა",
|
||||||
"disallow-password-auth": "პაროლით ავთენტიკაციის აკრძალვა",
|
"disallow-password-auth": "პაროლით ავთენტიკაციის აკრძალვა",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhook",
|
"title": "Webhook",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "닉네임 변경 금지",
|
"disallow-change-nickname": "닉네임 변경 금지",
|
||||||
"disallow-change-username": "유저네임 변경 금지",
|
"disallow-change-username": "유저네임 변경 금지",
|
||||||
"disallow-password-auth": "비밀번호 인증 금지",
|
"disallow-password-auth": "비밀번호 인증 금지",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "टोपणनाव बदलण्यास मनाई करा",
|
"disallow-change-nickname": "टोपणनाव बदलण्यास मनाई करा",
|
||||||
"disallow-change-username": "वापरकर्तानाव बदलण्यास मनाई करा",
|
"disallow-change-username": "वापरकर्तानाव बदलण्यास मनाई करा",
|
||||||
"disallow-password-auth": "पासवर्ड प्रमाणीकरणास मनाई करा",
|
"disallow-password-auth": "पासवर्ड प्रमाणीकरणास मनाई करा",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Ikke tillat endring av kallenavn",
|
"disallow-change-nickname": "Ikke tillat endring av kallenavn",
|
||||||
"disallow-change-username": "Ikke tillat endring av brukernavn",
|
"disallow-change-username": "Ikke tillat endring av brukernavn",
|
||||||
"disallow-password-auth": "Ikke tillat autentisering med passord",
|
"disallow-password-auth": "Ikke tillat autentisering med passord",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Wijzigen van bijnaam niet toestaan",
|
"disallow-change-nickname": "Wijzigen van bijnaam niet toestaan",
|
||||||
"disallow-change-username": "Wijzigen van gebruikersnaam niet toestaan",
|
"disallow-change-username": "Wijzigen van gebruikersnaam niet toestaan",
|
||||||
"disallow-password-auth": "Wachtwoordauthenticatie niet toestaan",
|
"disallow-password-auth": "Wachtwoordauthenticatie niet toestaan",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooki",
|
"title": "Webhooki",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Zabroń zmiany pseudonimu",
|
"disallow-change-nickname": "Zabroń zmiany pseudonimu",
|
||||||
"disallow-change-username": "Zabroń zmiany nazwy użytkownika",
|
"disallow-change-username": "Zabroń zmiany nazwy użytkownika",
|
||||||
"disallow-password-auth": "Zabroń uwierzytelniania hasłem",
|
"disallow-password-auth": "Zabroń uwierzytelniania hasłem",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Impedir troca de apelido",
|
"disallow-change-nickname": "Impedir troca de apelido",
|
||||||
"disallow-change-username": "Impedir troca de nome de usuário",
|
"disallow-change-username": "Impedir troca de nome de usuário",
|
||||||
"disallow-password-auth": "Impedir autenticação por senha",
|
"disallow-password-auth": "Impedir autenticação por senha",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Desativar alteração de apelido",
|
"disallow-change-nickname": "Desativar alteração de apelido",
|
||||||
"disallow-change-username": "Desativar alteração de nome de utilizador",
|
"disallow-change-username": "Desativar alteração de nome de utilizador",
|
||||||
"disallow-password-auth": "Desativar autenticação por palavra-passe",
|
"disallow-password-auth": "Desativar autenticação por palavra-passe",
|
||||||
|
|
|
||||||
|
|
@ -376,7 +376,7 @@
|
||||||
"title": "Вебхуки",
|
"title": "Вебхуки",
|
||||||
"url": "Ссылка"
|
"url": "Ссылка"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Запретить смену псевдонима",
|
"disallow-change-nickname": "Запретить смену псевдонима",
|
||||||
"disallow-change-username": "Запретить смену имени пользователя",
|
"disallow-change-username": "Запретить смену имени пользователя",
|
||||||
"disallow-password-auth": "Запретить вход по паролю",
|
"disallow-password-auth": "Запретить вход по паролю",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Onemogoči spremembo vzdevka",
|
"disallow-change-nickname": "Onemogoči spremembo vzdevka",
|
||||||
"disallow-change-username": "Onemogoči spremembo uporabniškega imena",
|
"disallow-change-username": "Onemogoči spremembo uporabniškega imena",
|
||||||
"disallow-password-auth": "Onemogoči preverjanje gesla",
|
"disallow-password-auth": "Onemogoči preverjanje gesla",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Förbjud ändring av smeknamn",
|
"disallow-change-nickname": "Förbjud ändring av smeknamn",
|
||||||
"disallow-change-username": "Förbjud ändring av användarnamn",
|
"disallow-change-username": "Förbjud ändring av användarnamn",
|
||||||
"disallow-password-auth": "Förbjud lösenordsautentisering",
|
"disallow-password-auth": "Förbjud lösenordsautentisering",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhooks",
|
"title": "Webhooks",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "ไม่อนุญาตให้เปลี่ยนชื่อเล่น",
|
"disallow-change-nickname": "ไม่อนุญาตให้เปลี่ยนชื่อเล่น",
|
||||||
"disallow-change-username": "ไม่อนุญาตให้เปลี่ยนชื่อผู้ใช้",
|
"disallow-change-username": "ไม่อนุญาตให้เปลี่ยนชื่อผู้ใช้",
|
||||||
"disallow-password-auth": "ไม่อนุญาตให้ยืนยันตัวตนด้วยรหัสผ่าน",
|
"disallow-password-auth": "ไม่อนุญาตให้ยืนยันตัวตนด้วยรหัสผ่าน",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Webhook'lar",
|
"title": "Webhook'lar",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Takma ad değiştirmeyi yasakla",
|
"disallow-change-nickname": "Takma ad değiştirmeyi yasakla",
|
||||||
"disallow-change-username": "Kullanıcı adı değiştirmeyi yasakla",
|
"disallow-change-username": "Kullanıcı adı değiştirmeyi yasakla",
|
||||||
"disallow-password-auth": "Şifre ile kimlik doğrulamayı yasakla",
|
"disallow-password-auth": "Şifre ile kimlik doğrulamayı yasakla",
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
"title": "Вебхуки",
|
"title": "Вебхуки",
|
||||||
"url": "URL"
|
"url": "URL"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Заборонити зміну нікнейму",
|
"disallow-change-nickname": "Заборонити зміну нікнейму",
|
||||||
"disallow-change-username": "Заборонити зміну імені користувача",
|
"disallow-change-username": "Заборонити зміну імені користувача",
|
||||||
"disallow-password-auth": "Заборонити авторизацію за паролем",
|
"disallow-password-auth": "Заборонити авторизацію за паролем",
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,7 @@
|
||||||
"title": "Webhook",
|
"title": "Webhook",
|
||||||
"url": "Url"
|
"url": "Url"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "Không cho phép đổi biệt danh",
|
"disallow-change-nickname": "Không cho phép đổi biệt danh",
|
||||||
"disallow-change-username": "Không cho phép đổi tên người dùng",
|
"disallow-change-username": "Không cho phép đổi tên người dùng",
|
||||||
"disallow-password-auth": "Không cho phép xác thực bằng mật khẩu",
|
"disallow-password-auth": "Không cho phép xác thực bằng mật khẩu",
|
||||||
|
|
|
||||||
|
|
@ -406,7 +406,7 @@
|
||||||
},
|
},
|
||||||
"no-webhooks-found": "没有 webhooks。"
|
"no-webhooks-found": "没有 webhooks。"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "禁止修改用户昵称",
|
"disallow-change-nickname": "禁止修改用户昵称",
|
||||||
"disallow-change-username": "禁止修改用户名",
|
"disallow-change-username": "禁止修改用户名",
|
||||||
"disallow-password-auth": "禁用密码登录",
|
"disallow-password-auth": "禁用密码登录",
|
||||||
|
|
|
||||||
|
|
@ -435,7 +435,7 @@
|
||||||
"title": "Webhook",
|
"title": "Webhook",
|
||||||
"url": "網址"
|
"url": "網址"
|
||||||
},
|
},
|
||||||
"workspace-section": {
|
"instance-section": {
|
||||||
"disallow-change-nickname": "禁止變更暱稱",
|
"disallow-change-nickname": "禁止變更暱稱",
|
||||||
"disallow-change-username": "禁止變更使用者名稱",
|
"disallow-change-username": "禁止變更使用者名稱",
|
||||||
"disallow-password-auth": "禁止使用密碼登入",
|
"disallow-password-auth": "禁止使用密碼登入",
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ import "./index.css";
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
// Configure MobX before importing any stores
|
// Configure MobX before importing any stores
|
||||||
import "./store/config";
|
import "./store/config";
|
||||||
|
import { initialInstanceStore } from "./store/instance";
|
||||||
import { initialUserStore } from "./store/user";
|
import { initialUserStore } from "./store/user";
|
||||||
import { initialWorkspaceStore } from "./store/workspace";
|
|
||||||
import { applyThemeEarly } from "./utils/theme";
|
import { applyThemeEarly } from "./utils/theme";
|
||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
|
|
||||||
|
|
@ -24,7 +24,7 @@ const Main = observer(() => (
|
||||||
));
|
));
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
await initialWorkspaceStore();
|
await initialInstanceStore();
|
||||||
await initialUserStore();
|
await initialUserStore();
|
||||||
|
|
||||||
const container = document.getElementById("root");
|
const container = document.getElementById("root");
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import AuthFooter from "@/components/AuthFooter";
|
import AuthFooter from "@/components/AuthFooter";
|
||||||
import PasswordSignInForm from "@/components/PasswordSignInForm";
|
import PasswordSignInForm from "@/components/PasswordSignInForm";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
|
|
||||||
const AdminSignIn = observer(() => {
|
const AdminSignIn = observer(() => {
|
||||||
const workspaceGeneralSetting = workspaceStore.state.generalSetting;
|
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="py-4 sm:py-8 w-80 max-w-full min-h-svh mx-auto flex flex-col justify-start items-center">
|
<div className="py-4 sm:py-8 w-80 max-w-full min-h-svh mx-auto flex flex-col justify-start items-center">
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="w-full flex flex-row justify-center items-center mb-6">
|
<div className="w-full flex flex-row justify-center items-center mb-6">
|
||||||
<img className="h-14 w-auto rounded-full shadow" src={workspaceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={instanceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
||||||
<p className="ml-2 text-5xl text-foreground opacity-80">{workspaceGeneralSetting.customProfile?.title || "Memos"}</p>
|
<p className="ml-2 text-5xl text-foreground opacity-80">{instanceGeneralSetting.customProfile?.title || "Memos"}</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="w-full text-xl font-medium text-muted-foreground">Sign in with admin accounts</p>
|
<p className="w-full text-xl font-medium text-muted-foreground">Sign in with admin accounts</p>
|
||||||
<PasswordSignInForm />
|
<PasswordSignInForm />
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { observer } from "mobx-react-lite";
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import MobileHeader from "@/components/MobileHeader";
|
import MobileHeader from "@/components/MobileHeader";
|
||||||
|
import InstanceSection from "@/components/Settings/InstanceSection";
|
||||||
import MemberSection from "@/components/Settings/MemberSection";
|
import MemberSection from "@/components/Settings/MemberSection";
|
||||||
import MemoRelatedSettings from "@/components/Settings/MemoRelatedSettings";
|
import MemoRelatedSettings from "@/components/Settings/MemoRelatedSettings";
|
||||||
import MyAccountSection from "@/components/Settings/MyAccountSection";
|
import MyAccountSection from "@/components/Settings/MyAccountSection";
|
||||||
|
|
@ -10,13 +11,12 @@ import PreferencesSection from "@/components/Settings/PreferencesSection";
|
||||||
import SSOSection from "@/components/Settings/SSOSection";
|
import SSOSection from "@/components/Settings/SSOSection";
|
||||||
import SectionMenuItem from "@/components/Settings/SectionMenuItem";
|
import SectionMenuItem from "@/components/Settings/SectionMenuItem";
|
||||||
import StorageSection from "@/components/Settings/StorageSection";
|
import StorageSection from "@/components/Settings/StorageSection";
|
||||||
import WorkspaceSection from "@/components/Settings/WorkspaceSection";
|
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||||
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
|
import { InstanceSetting_Key } from "@/types/proto/api/v1/instance_service";
|
||||||
import { User_Role } from "@/types/proto/api/v1/user_service";
|
import { User_Role } from "@/types/proto/api/v1/user_service";
|
||||||
import { WorkspaceSetting_Key } from "@/types/proto/api/v1/workspace_service";
|
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
||||||
type SettingSection = "my-account" | "preference" | "member" | "system" | "memo-related" | "storage" | "sso";
|
type SettingSection = "my-account" | "preference" | "member" | "system" | "memo-related" | "storage" | "sso";
|
||||||
|
|
@ -71,10 +71,10 @@ const Setting = observer(() => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial fetch for workspace settings.
|
// Initial fetch for instance settings.
|
||||||
(async () => {
|
(async () => {
|
||||||
[WorkspaceSetting_Key.MEMO_RELATED, WorkspaceSetting_Key.STORAGE].forEach(async (key) => {
|
[InstanceSetting_Key.MEMO_RELATED, InstanceSetting_Key.STORAGE].forEach(async (key) => {
|
||||||
await workspaceStore.fetchWorkspaceSetting(key);
|
await instanceStore.fetchInstanceSetting(key);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
}, [isHost]);
|
}, [isHost]);
|
||||||
|
|
@ -115,7 +115,7 @@ const Setting = observer(() => {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<span className="px-3 mt-2 opacity-70 text-sm">
|
<span className="px-3 mt-2 opacity-70 text-sm">
|
||||||
{t("setting.version")}: v{workspaceStore.state.profile.version}
|
{t("setting.version")}: v{instanceStore.state.profile.version}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
@ -143,7 +143,7 @@ const Setting = observer(() => {
|
||||||
) : state.selectedSection === "member" ? (
|
) : state.selectedSection === "member" ? (
|
||||||
<MemberSection />
|
<MemberSection />
|
||||||
) : state.selectedSection === "system" ? (
|
) : state.selectedSection === "system" ? (
|
||||||
<WorkspaceSection />
|
<InstanceSection />
|
||||||
) : state.selectedSection === "memo-related" ? (
|
) : state.selectedSection === "memo-related" ? (
|
||||||
<MemoRelatedSettings />
|
<MemoRelatedSettings />
|
||||||
) : state.selectedSection === "storage" ? (
|
) : state.selectedSection === "storage" ? (
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { identityProviderServiceClient } from "@/grpcweb";
|
||||||
import { absolutifyLink } from "@/helpers/utils";
|
import { absolutifyLink } from "@/helpers/utils";
|
||||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||||
import { Routes } from "@/router";
|
import { Routes } from "@/router";
|
||||||
import { workspaceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { extractIdentityProviderIdFromName } from "@/store/common";
|
import { extractIdentityProviderIdFromName } from "@/store/common";
|
||||||
import { IdentityProvider, IdentityProvider_Type } from "@/types/proto/api/v1/idp_service";
|
import { IdentityProvider, IdentityProvider_Type } from "@/types/proto/api/v1/idp_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
@ -20,7 +20,7 @@ const SignIn = observer(() => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const currentUser = useCurrentUser();
|
const currentUser = useCurrentUser();
|
||||||
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
|
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
|
||||||
const workspaceGeneralSetting = workspaceStore.state.generalSetting;
|
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||||
|
|
||||||
// Redirect to root page if already signed in.
|
// Redirect to root page if already signed in.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -71,15 +71,15 @@ const SignIn = observer(() => {
|
||||||
<div className="py-4 sm:py-8 w-80 max-w-full min-h-svh mx-auto flex flex-col justify-start items-center">
|
<div className="py-4 sm:py-8 w-80 max-w-full min-h-svh mx-auto flex flex-col justify-start items-center">
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="w-full flex flex-row justify-center items-center mb-6">
|
<div className="w-full flex flex-row justify-center items-center mb-6">
|
||||||
<img className="h-14 w-auto rounded-full shadow" src={workspaceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={instanceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
||||||
<p className="ml-2 text-5xl text-foreground opacity-80">{workspaceGeneralSetting.customProfile?.title || "Memos"}</p>
|
<p className="ml-2 text-5xl text-foreground opacity-80">{instanceGeneralSetting.customProfile?.title || "Memos"}</p>
|
||||||
</div>
|
</div>
|
||||||
{!workspaceGeneralSetting.disallowPasswordAuth ? (
|
{!instanceGeneralSetting.disallowPasswordAuth ? (
|
||||||
<PasswordSignInForm />
|
<PasswordSignInForm />
|
||||||
) : (
|
) : (
|
||||||
identityProviderList.length == 0 && <p className="w-full text-2xl mt-2 text-muted-foreground">Password auth is not allowed.</p>
|
identityProviderList.length == 0 && <p className="w-full text-2xl mt-2 text-muted-foreground">Password auth is not allowed.</p>
|
||||||
)}
|
)}
|
||||||
{!workspaceGeneralSetting.disallowUserRegistration && !workspaceGeneralSetting.disallowPasswordAuth && (
|
{!instanceGeneralSetting.disallowUserRegistration && !instanceGeneralSetting.disallowPasswordAuth && (
|
||||||
<p className="w-full mt-4 text-sm">
|
<p className="w-full mt-4 text-sm">
|
||||||
<span className="text-muted-foreground">{t("auth.sign-up-tip")}</span>
|
<span className="text-muted-foreground">{t("auth.sign-up-tip")}</span>
|
||||||
<Link to="/auth/signup" className="cursor-pointer ml-2 text-primary hover:underline" viewTransition>
|
<Link to="/auth/signup" className="cursor-pointer ml-2 text-primary hover:underline" viewTransition>
|
||||||
|
|
@ -89,7 +89,7 @@ const SignIn = observer(() => {
|
||||||
)}
|
)}
|
||||||
{identityProviderList.length > 0 && (
|
{identityProviderList.length > 0 && (
|
||||||
<>
|
<>
|
||||||
{!workspaceGeneralSetting.disallowPasswordAuth && (
|
{!instanceGeneralSetting.disallowPasswordAuth && (
|
||||||
<div className="relative my-4 w-full">
|
<div className="relative my-4 w-full">
|
||||||
<Separator />
|
<Separator />
|
||||||
<div className="absolute inset-0 flex items-center justify-center">
|
<div className="absolute inset-0 flex items-center justify-center">
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue