mirror of
https://github.com/aykhans/slash-e.git
synced 2025-06-06 16:49:01 +00:00
feat: implement frontend ssr service
This commit is contained in:
parent
6eb3ff412d
commit
dbd3888fe1
@ -6,6 +6,7 @@
|
|||||||
<meta name="theme-color" content="#FFFFFF" />
|
<meta name="theme-color" content="#FFFFFF" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||||
<title>Slash</title>
|
<title>Slash</title>
|
||||||
|
<!-- slash.metadata -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
@ -416,6 +416,7 @@
|
|||||||
| custom_style | [string](#string) | | |
|
| custom_style | [string](#string) | | |
|
||||||
| custom_script | [string](#string) | | |
|
| custom_script | [string](#string) | | |
|
||||||
| auto_backup | [AutoBackupWorkspaceSetting](#slash-store-AutoBackupWorkspaceSetting) | | |
|
| auto_backup | [AutoBackupWorkspaceSetting](#slash-store-AutoBackupWorkspaceSetting) | | |
|
||||||
|
| instance_url | [string](#string) | | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -438,6 +439,7 @@
|
|||||||
| WORKSPACE_SETTING_CUSTOM_STYLE | 4 | The custom style. |
|
| WORKSPACE_SETTING_CUSTOM_STYLE | 4 | The custom style. |
|
||||||
| WORKSPACE_SETTING_CUSTOM_SCRIPT | 5 | The custom script. |
|
| WORKSPACE_SETTING_CUSTOM_SCRIPT | 5 | The custom script. |
|
||||||
| WORKSPACE_SETTING_AUTO_BACKUP | 6 | The auto backup setting. |
|
| WORKSPACE_SETTING_AUTO_BACKUP | 6 | The auto backup setting. |
|
||||||
|
| WORKSPACE_SETTING_INSTANCE_URL | 7 | The instance URL. |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ const (
|
|||||||
WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_SCRIPT WorkspaceSettingKey = 5
|
WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_SCRIPT WorkspaceSettingKey = 5
|
||||||
// The auto backup setting.
|
// The auto backup setting.
|
||||||
WorkspaceSettingKey_WORKSPACE_SETTING_AUTO_BACKUP WorkspaceSettingKey = 6
|
WorkspaceSettingKey_WORKSPACE_SETTING_AUTO_BACKUP WorkspaceSettingKey = 6
|
||||||
|
// The instance URL.
|
||||||
|
WorkspaceSettingKey_WORKSPACE_SETTING_INSTANCE_URL WorkspaceSettingKey = 7
|
||||||
)
|
)
|
||||||
|
|
||||||
// Enum value maps for WorkspaceSettingKey.
|
// Enum value maps for WorkspaceSettingKey.
|
||||||
@ -48,6 +50,7 @@ var (
|
|||||||
4: "WORKSPACE_SETTING_CUSTOM_STYLE",
|
4: "WORKSPACE_SETTING_CUSTOM_STYLE",
|
||||||
5: "WORKSPACE_SETTING_CUSTOM_SCRIPT",
|
5: "WORKSPACE_SETTING_CUSTOM_SCRIPT",
|
||||||
6: "WORKSPACE_SETTING_AUTO_BACKUP",
|
6: "WORKSPACE_SETTING_AUTO_BACKUP",
|
||||||
|
7: "WORKSPACE_SETTING_INSTANCE_URL",
|
||||||
}
|
}
|
||||||
WorkspaceSettingKey_value = map[string]int32{
|
WorkspaceSettingKey_value = map[string]int32{
|
||||||
"WORKSPACE_SETTING_KEY_UNSPECIFIED": 0,
|
"WORKSPACE_SETTING_KEY_UNSPECIFIED": 0,
|
||||||
@ -57,6 +60,7 @@ var (
|
|||||||
"WORKSPACE_SETTING_CUSTOM_STYLE": 4,
|
"WORKSPACE_SETTING_CUSTOM_STYLE": 4,
|
||||||
"WORKSPACE_SETTING_CUSTOM_SCRIPT": 5,
|
"WORKSPACE_SETTING_CUSTOM_SCRIPT": 5,
|
||||||
"WORKSPACE_SETTING_AUTO_BACKUP": 6,
|
"WORKSPACE_SETTING_AUTO_BACKUP": 6,
|
||||||
|
"WORKSPACE_SETTING_INSTANCE_URL": 7,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -101,6 +105,7 @@ type WorkspaceSetting struct {
|
|||||||
// *WorkspaceSetting_CustomStyle
|
// *WorkspaceSetting_CustomStyle
|
||||||
// *WorkspaceSetting_CustomScript
|
// *WorkspaceSetting_CustomScript
|
||||||
// *WorkspaceSetting_AutoBackup
|
// *WorkspaceSetting_AutoBackup
|
||||||
|
// *WorkspaceSetting_InstanceUrl
|
||||||
Value isWorkspaceSetting_Value `protobuf_oneof:"value"`
|
Value isWorkspaceSetting_Value `protobuf_oneof:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +197,13 @@ func (x *WorkspaceSetting) GetAutoBackup() *AutoBackupWorkspaceSetting {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *WorkspaceSetting) GetInstanceUrl() string {
|
||||||
|
if x, ok := x.GetValue().(*WorkspaceSetting_InstanceUrl); ok {
|
||||||
|
return x.InstanceUrl
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type isWorkspaceSetting_Value interface {
|
type isWorkspaceSetting_Value interface {
|
||||||
isWorkspaceSetting_Value()
|
isWorkspaceSetting_Value()
|
||||||
}
|
}
|
||||||
@ -220,6 +232,10 @@ type WorkspaceSetting_AutoBackup struct {
|
|||||||
AutoBackup *AutoBackupWorkspaceSetting `protobuf:"bytes,7,opt,name=auto_backup,json=autoBackup,proto3,oneof"`
|
AutoBackup *AutoBackupWorkspaceSetting `protobuf:"bytes,7,opt,name=auto_backup,json=autoBackup,proto3,oneof"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WorkspaceSetting_InstanceUrl struct {
|
||||||
|
InstanceUrl string `protobuf:"bytes,8,opt,name=instance_url,json=instanceUrl,proto3,oneof"`
|
||||||
|
}
|
||||||
|
|
||||||
func (*WorkspaceSetting_LicenseKey) isWorkspaceSetting_Value() {}
|
func (*WorkspaceSetting_LicenseKey) isWorkspaceSetting_Value() {}
|
||||||
|
|
||||||
func (*WorkspaceSetting_SecretSession) isWorkspaceSetting_Value() {}
|
func (*WorkspaceSetting_SecretSession) isWorkspaceSetting_Value() {}
|
||||||
@ -232,6 +248,8 @@ func (*WorkspaceSetting_CustomScript) isWorkspaceSetting_Value() {}
|
|||||||
|
|
||||||
func (*WorkspaceSetting_AutoBackup) isWorkspaceSetting_Value() {}
|
func (*WorkspaceSetting_AutoBackup) isWorkspaceSetting_Value() {}
|
||||||
|
|
||||||
|
func (*WorkspaceSetting_InstanceUrl) isWorkspaceSetting_Value() {}
|
||||||
|
|
||||||
type AutoBackupWorkspaceSetting struct {
|
type AutoBackupWorkspaceSetting struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@ -305,7 +323,7 @@ var File_store_workspace_setting_proto protoreflect.FileDescriptor
|
|||||||
var file_store_workspace_setting_proto_rawDesc = []byte{
|
var file_store_workspace_setting_proto_rawDesc = []byte{
|
||||||
0x0a, 0x1d, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
|
0x0a, 0x1d, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
|
||||||
0x65, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
|
0x65, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
|
||||||
0x0b, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xda, 0x02, 0x0a,
|
0x0b, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xff, 0x02, 0x0a,
|
||||||
0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
||||||
0x67, 0x12, 0x32, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20,
|
0x67, 0x12, 0x32, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20,
|
||||||
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x57, 0x6f, 0x72,
|
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x57, 0x6f, 0x72,
|
||||||
@ -327,43 +345,48 @@ var file_store_workspace_setting_proto_rawDesc = []byte{
|
|||||||
0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b,
|
0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b,
|
||||||
0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69,
|
0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69,
|
||||||
0x6e, 0x67, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70,
|
0x6e, 0x67, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70,
|
||||||
0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7a, 0x0a, 0x1a, 0x41, 0x75, 0x74,
|
0x12, 0x23, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6c,
|
||||||
0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
|
0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
|
||||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c,
|
0x63, 0x65, 0x55, 0x72, 0x6c, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7a,
|
||||||
0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65,
|
0x0a, 0x1a, 0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b,
|
||||||
0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73,
|
0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07,
|
||||||
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e,
|
0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65,
|
||||||
0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61,
|
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x65,
|
||||||
0x78, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61,
|
0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
0x78, 0x4b, 0x65, 0x65, 0x70, 0x2a, 0x96, 0x02, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
|
0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12,
|
||||||
0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x0a,
|
0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||||
0x21, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49,
|
0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x4b, 0x65, 0x65, 0x70, 0x2a, 0xba, 0x02, 0x0a, 0x13, 0x57,
|
||||||
0x4e, 0x47, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4b,
|
||||||
0x45, 0x44, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43,
|
0x65, 0x79, 0x12, 0x25, 0x0a, 0x21, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f,
|
||||||
0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53,
|
0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50,
|
||||||
0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x57, 0x4f, 0x52, 0x4b, 0x53,
|
0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x57, 0x4f, 0x52,
|
||||||
0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x45, 0x43,
|
0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4c,
|
||||||
0x52, 0x45, 0x54, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x23, 0x0a,
|
0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20,
|
||||||
0x1f, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x41, 0x50, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49,
|
0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e,
|
||||||
0x4e, 0x47, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x55, 0x50,
|
0x47, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e,
|
||||||
0x10, 0x03, 0x12, 0x22, 0x0a, 0x1e, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f,
|
0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x41, 0x50, 0x43, 0x45, 0x5f,
|
||||||
0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x5f, 0x53,
|
0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x53,
|
||||||
0x54, 0x59, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50,
|
0x49, 0x47, 0x4e, 0x55, 0x50, 0x10, 0x03, 0x12, 0x22, 0x0a, 0x1e, 0x57, 0x4f, 0x52, 0x4b, 0x53,
|
||||||
0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x55, 0x53, 0x54,
|
0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x55, 0x53,
|
||||||
0x4f, 0x4d, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x10, 0x05, 0x12, 0x21, 0x0a, 0x1d, 0x57,
|
0x54, 0x4f, 0x4d, 0x5f, 0x53, 0x54, 0x59, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x57,
|
||||||
0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47,
|
0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47,
|
||||||
0x5f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x10, 0x06, 0x42, 0xa6,
|
0x5f, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x10, 0x05,
|
||||||
0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f,
|
0x12, 0x21, 0x0a, 0x1d, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45,
|
||||||
0x72, 0x65, 0x42, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74,
|
0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x55,
|
||||||
0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74,
|
0x50, 0x10, 0x06, 0x12, 0x22, 0x0a, 0x1e, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45,
|
||||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x79, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x6c, 0x66,
|
0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43,
|
||||||
0x68, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f,
|
0x45, 0x5f, 0x55, 0x52, 0x4c, 0x10, 0x07, 0x42, 0xa6, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e,
|
||||||
0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x53,
|
0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x15, 0x57, 0x6f, 0x72,
|
||||||
0x53, 0x58, 0xaa, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65,
|
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f,
|
||||||
0xca, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02,
|
0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||||
0x17, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42,
|
0x2f, 0x79, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x6c, 0x66, 0x68, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x2f,
|
||||||
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68,
|
0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f,
|
||||||
0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x53, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x53, 0x6c,
|
||||||
|
0x61, 0x73, 0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73,
|
||||||
|
0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c,
|
||||||
|
0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||||
|
0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65,
|
||||||
|
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -433,6 +456,7 @@ func file_store_workspace_setting_proto_init() {
|
|||||||
(*WorkspaceSetting_CustomStyle)(nil),
|
(*WorkspaceSetting_CustomStyle)(nil),
|
||||||
(*WorkspaceSetting_CustomScript)(nil),
|
(*WorkspaceSetting_CustomScript)(nil),
|
||||||
(*WorkspaceSetting_AutoBackup)(nil),
|
(*WorkspaceSetting_AutoBackup)(nil),
|
||||||
|
(*WorkspaceSetting_InstanceUrl)(nil),
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
|
@ -14,6 +14,7 @@ message WorkspaceSetting {
|
|||||||
string custom_style = 5;
|
string custom_style = 5;
|
||||||
string custom_script = 6;
|
string custom_script = 6;
|
||||||
AutoBackupWorkspaceSetting auto_backup = 7;
|
AutoBackupWorkspaceSetting auto_backup = 7;
|
||||||
|
string instance_url = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +32,8 @@ enum WorkspaceSettingKey {
|
|||||||
WORKSPACE_SETTING_CUSTOM_SCRIPT = 5;
|
WORKSPACE_SETTING_CUSTOM_SCRIPT = 5;
|
||||||
// The auto backup setting.
|
// The auto backup setting.
|
||||||
WORKSPACE_SETTING_AUTO_BACKUP = 6;
|
WORKSPACE_SETTING_AUTO_BACKUP = 6;
|
||||||
|
// The instance URL.
|
||||||
|
WORKSPACE_SETTING_INSTANCE_URL = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AutoBackupWorkspaceSetting {
|
message AutoBackupWorkspaceSetting {
|
||||||
|
@ -2,18 +2,162 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
|
|
||||||
"github.com/yourselfhosted/slash/internal/util"
|
"github.com/yourselfhosted/slash/internal/util"
|
||||||
|
storepb "github.com/yourselfhosted/slash/proto/gen/store"
|
||||||
|
"github.com/yourselfhosted/slash/server/profile"
|
||||||
|
"github.com/yourselfhosted/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed dist
|
//go:embed dist
|
||||||
var embeddedFiles embed.FS
|
var embeddedFiles embed.FS
|
||||||
|
|
||||||
|
//go:embed dist/index.html
|
||||||
|
var rawIndexHTML string
|
||||||
|
|
||||||
|
type FrontendService struct {
|
||||||
|
Profile *profile.Profile
|
||||||
|
Store *store.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFrontendService(profile *profile.Profile, store *store.Store) *FrontendService {
|
||||||
|
return &FrontendService{
|
||||||
|
Profile: profile,
|
||||||
|
Store: store,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FrontendService) Serve(e *echo.Echo) {
|
||||||
|
// Use echo static middleware to serve the built dist folder.
|
||||||
|
// refer: https://github.com/labstack/echo/blob/master/middleware/static.go
|
||||||
|
e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
|
||||||
|
Skipper: defaultRequestSkipper,
|
||||||
|
HTML5: true,
|
||||||
|
Filesystem: getFileSystem("dist"),
|
||||||
|
}))
|
||||||
|
|
||||||
|
assetsGroup := e.Group("assets")
|
||||||
|
assetsGroup.Use(middleware.GzipWithConfig(middleware.GzipConfig{
|
||||||
|
Skipper: defaultRequestSkipper,
|
||||||
|
Level: 5,
|
||||||
|
}))
|
||||||
|
assetsGroup.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
c.Response().Header().Set(echo.HeaderCacheControl, "max-age=31536000, immutable")
|
||||||
|
return next(c)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
assetsGroup.Use(middleware.StaticWithConfig(middleware.StaticConfig{
|
||||||
|
Skipper: defaultRequestSkipper,
|
||||||
|
HTML5: true,
|
||||||
|
Filesystem: getFileSystem("dist/assets"),
|
||||||
|
}))
|
||||||
|
s.registerRoutes(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FrontendService) registerRoutes(e *echo.Echo) {
|
||||||
|
e.GET("/robots.txt", func(c echo.Context) error {
|
||||||
|
ctx := c.Request().Context()
|
||||||
|
instanceURLSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
|
||||||
|
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_INSTANCE_URL,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to get instance URL system setting").SetInternal(err)
|
||||||
|
}
|
||||||
|
if instanceURLSetting == nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Instance URL system setting is not set")
|
||||||
|
}
|
||||||
|
instanceURL := instanceURLSetting.GetInstanceUrl()
|
||||||
|
robotsTxt := fmt.Sprintf(`User-agent: *
|
||||||
|
Allow: /
|
||||||
|
Host: %s
|
||||||
|
Sitemap: %s/sitemap.xml`, instanceURL, instanceURL)
|
||||||
|
return c.String(http.StatusOK, robotsTxt)
|
||||||
|
})
|
||||||
|
|
||||||
|
e.GET("/sitemap.xml", func(c echo.Context) error {
|
||||||
|
ctx := c.Request().Context()
|
||||||
|
instanceURLSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
|
||||||
|
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_INSTANCE_URL,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to get instance URL system setting").SetInternal(err)
|
||||||
|
}
|
||||||
|
if instanceURLSetting == nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Instance URL system setting is not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceURL := instanceURLSetting.GetInstanceUrl()
|
||||||
|
urlsets := []string{}
|
||||||
|
// Append shortcut list.
|
||||||
|
shortcuts, err := s.Store.ListShortcuts(ctx, &store.FindShortcut{
|
||||||
|
VisibilityList: []store.Visibility{store.VisibilityPublic},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, shortcut := range shortcuts {
|
||||||
|
urlsets = append(urlsets, fmt.Sprintf(`<url><loc>%s/s/%s</loc></url>`, instanceURL, shortcut.Name))
|
||||||
|
}
|
||||||
|
// Append collection list.
|
||||||
|
collections, err := s.Store.ListCollections(ctx, &store.FindCollection{
|
||||||
|
VisibilityList: []store.Visibility{store.VisibilityPublic},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, collection := range collections {
|
||||||
|
urlsets = append(urlsets, fmt.Sprintf(`<url><loc>%s/c/%s</loc></url>`, instanceURL, collection.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
sitemap := fmt.Sprintf(`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">%s</urlset>`, strings.Join(urlsets, "\n"))
|
||||||
|
return c.XMLBlob(http.StatusOK, []byte(sitemap))
|
||||||
|
})
|
||||||
|
|
||||||
|
e.GET("/s/:shortcutName", func(c echo.Context) error {
|
||||||
|
ctx := c.Request().Context()
|
||||||
|
shortcutName := c.Param("shortcutName")
|
||||||
|
shortcut, err := s.Store.GetShortcut(ctx, &store.FindShortcut{
|
||||||
|
Name: &shortcutName,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return c.HTML(http.StatusOK, rawIndexHTML)
|
||||||
|
}
|
||||||
|
if shortcut == nil {
|
||||||
|
return c.HTML(http.StatusOK, rawIndexHTML)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject shortcut metadata into `index.html`.
|
||||||
|
indexHTML := strings.ReplaceAll(rawIndexHTML, "<!-- slash.metadata -->", generateShortcutMetadata(shortcut))
|
||||||
|
return c.HTML(http.StatusOK, indexHTML)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateShortcutMetadata(shortcut *storepb.Shortcut) string {
|
||||||
|
metadataList := []string{
|
||||||
|
fmt.Sprintf(`<title>%s</title>`, shortcut.OgMetadata.Title),
|
||||||
|
fmt.Sprintf(`<meta name="description" content="%s" />`, shortcut.OgMetadata.Description),
|
||||||
|
fmt.Sprintf(`<meta property="og:title" content="%s" />`, shortcut.OgMetadata.Title),
|
||||||
|
fmt.Sprintf(`<meta property="og:description" content="%s" />`, shortcut.OgMetadata.Description),
|
||||||
|
fmt.Sprintf(`<meta property="og:image" content="%s" />`, shortcut.OgMetadata.Image),
|
||||||
|
`<meta property="og:type" content="website" />`,
|
||||||
|
// Twitter related metadata.
|
||||||
|
fmt.Sprintf(`<meta name="twitter:title" content="%s" />`, shortcut.OgMetadata.Title),
|
||||||
|
fmt.Sprintf(`<meta name="twitter:description" content="%s" />`, shortcut.OgMetadata.Description),
|
||||||
|
fmt.Sprintf(`<meta name="twitter:image" content="%s" />`, shortcut.OgMetadata.Image),
|
||||||
|
`<meta name="twitter:card" content="summary_large_image" />`,
|
||||||
|
fmt.Sprintf(`<meta property="og:url" content="%s" />`, shortcut.Link),
|
||||||
|
}
|
||||||
|
return strings.Join(metadataList, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
func getFileSystem(path string) http.FileSystem {
|
func getFileSystem(path string) http.FileSystem {
|
||||||
fs, err := fs.Sub(embeddedFiles, path)
|
fs, err := fs.Sub(embeddedFiles, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -25,28 +169,5 @@ func getFileSystem(path string) http.FileSystem {
|
|||||||
|
|
||||||
func defaultRequestSkipper(c echo.Context) bool {
|
func defaultRequestSkipper(c echo.Context) bool {
|
||||||
path := c.Path()
|
path := c.Path()
|
||||||
return util.HasPrefixes(path, "/api/", "/s/*")
|
return util.HasPrefixes(path, "/api/")
|
||||||
}
|
|
||||||
|
|
||||||
func embedFrontend(e *echo.Echo) {
|
|
||||||
// Use echo static middleware to serve the built dist folder
|
|
||||||
// refer: https://github.com/labstack/echo/blob/master/middleware/static.go
|
|
||||||
e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
|
|
||||||
Skipper: defaultRequestSkipper,
|
|
||||||
HTML5: true,
|
|
||||||
Filesystem: getFileSystem("dist"),
|
|
||||||
}))
|
|
||||||
|
|
||||||
assetsGroup := e.Group("assets")
|
|
||||||
assetsGroup.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
|
||||||
return func(c echo.Context) error {
|
|
||||||
c.Response().Header().Set(echo.HeaderCacheControl, "max-age=31536000, immutable")
|
|
||||||
return next(c)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
assetsGroup.Use(middleware.StaticWithConfig(middleware.StaticConfig{
|
|
||||||
Skipper: defaultRequestSkipper,
|
|
||||||
HTML5: true,
|
|
||||||
Filesystem: getFileSystem("dist/assets"),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,9 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
embedFrontend(e)
|
// Serve frontend.
|
||||||
|
frontendService := NewFrontendService(profile, store)
|
||||||
|
frontendService.Serve(e)
|
||||||
|
|
||||||
// In dev mode, we'd like to set the const secret key to make signin session persistence.
|
// In dev mode, we'd like to set the const secret key to make signin session persistence.
|
||||||
secret := "slash"
|
secret := "slash"
|
||||||
|
@ -39,6 +39,8 @@ func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *storepb.Workspa
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
valueString = string(valueBytes)
|
valueString = string(valueBytes)
|
||||||
|
} else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_INSTANCE_URL {
|
||||||
|
valueString = upsert.GetInstanceUrl()
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.New("invalid workspace setting key")
|
return nil, errors.New("invalid workspace setting key")
|
||||||
}
|
}
|
||||||
@ -102,6 +104,8 @@ func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspac
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_AutoBackup{AutoBackup: autoBackupSetting}
|
workspaceSetting.Value = &storepb.WorkspaceSetting_AutoBackup{AutoBackup: autoBackupSetting}
|
||||||
|
} else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_INSTANCE_URL {
|
||||||
|
workspaceSetting.Value = &storepb.WorkspaceSetting_InstanceUrl{InstanceUrl: valueString}
|
||||||
} else {
|
} else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *storepb.Workspa
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
valueString = string(valueBytes)
|
valueString = string(valueBytes)
|
||||||
|
} else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_INSTANCE_URL {
|
||||||
|
valueString = upsert.GetInstanceUrl()
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.New("invalid workspace setting key")
|
return nil, errors.New("invalid workspace setting key")
|
||||||
}
|
}
|
||||||
@ -102,6 +104,8 @@ func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspac
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
workspaceSetting.Value = &storepb.WorkspaceSetting_AutoBackup{AutoBackup: autoBackupSetting}
|
workspaceSetting.Value = &storepb.WorkspaceSetting_AutoBackup{AutoBackup: autoBackupSetting}
|
||||||
|
} else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_INSTANCE_URL {
|
||||||
|
workspaceSetting.Value = &storepb.WorkspaceSetting_InstanceUrl{InstanceUrl: valueString}
|
||||||
} else {
|
} else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user