Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
b2154266
Commit
b2154266
authored
May 29, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: update general setting
parent
423861d4
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
242 additions
and
458 deletions
+242
-458
apidocs.swagger.yaml
docs/apidocs.swagger.yaml
+0
-3
workspace_setting_service.proto
proto/api/v1/workspace_setting_service.proto
+5
-7
workspace_setting_service.pb.go
proto/gen/api/v1/workspace_setting_service.pb.go
+125
-136
workspace_setting.pb.go
proto/gen/store/workspace_setting.pb.go
+103
-114
workspace_setting.proto
proto/store/workspace_setting.proto
+5
-7
workspace_setting_service.go
server/router/api/v1/workspace_setting_service.go
+0
-2
frontend.go
server/router/frontend/frontend.go
+4
-141
WorkspaceSection.tsx
web/src/components/Settings/WorkspaceSection.tsx
+0
-48
No files found.
docs/apidocs.swagger.yaml
View file @
b2154266
...
@@ -2077,9 +2077,6 @@ definitions:
...
@@ -2077,9 +2077,6 @@ definitions:
apiv1WorkspaceGeneralSetting
:
apiv1WorkspaceGeneralSetting
:
type
:
object
type
:
object
properties
:
properties
:
instanceUrl
:
type
:
string
description
:
instance_url is the instance URL.
disallowSignup
:
disallowSignup
:
type
:
boolean
type
:
boolean
description
:
disallow_signup is the flag to disallow signup.
description
:
disallow_signup is the flag to disallow signup.
...
...
proto/api/v1/workspace_setting_service.proto
View file @
b2154266
...
@@ -36,18 +36,16 @@ message WorkspaceSetting {
...
@@ -36,18 +36,16 @@ message WorkspaceSetting {
}
}
message
WorkspaceGeneralSetting
{
message
WorkspaceGeneralSetting
{
// instance_url is the instance URL.
string
instance_url
=
1
;
// disallow_signup is the flag to disallow signup.
// disallow_signup is the flag to disallow signup.
bool
disallow_signup
=
2
;
bool
disallow_signup
=
1
;
// disallow_password_login is the flag to disallow password login.
// disallow_password_login is the flag to disallow password login.
bool
disallow_password_login
=
3
;
bool
disallow_password_login
=
2
;
// additional_script is the additional script.
// additional_script is the additional script.
string
additional_script
=
4
;
string
additional_script
=
3
;
// additional_style is the additional style.
// additional_style is the additional style.
string
additional_style
=
5
;
string
additional_style
=
4
;
// custom_profile is the custom profile.
// custom_profile is the custom profile.
WorkspaceCustomProfile
custom_profile
=
6
;
WorkspaceCustomProfile
custom_profile
=
5
;
}
}
message
WorkspaceCustomProfile
{
message
WorkspaceCustomProfile
{
...
...
proto/gen/api/v1/workspace_setting_service.pb.go
View file @
b2154266
This diff is collapsed.
Click to expand it.
proto/gen/store/workspace_setting.pb.go
View file @
b2154266
This diff is collapsed.
Click to expand it.
proto/store/workspace_setting.proto
View file @
b2154266
...
@@ -31,18 +31,16 @@ message WorkspaceBasicSetting {
...
@@ -31,18 +31,16 @@ message WorkspaceBasicSetting {
}
}
message
WorkspaceGeneralSetting
{
message
WorkspaceGeneralSetting
{
// instance_url is the instance URL.
string
instance_url
=
1
;
// disallow_signup is the flag to disallow signup.
// disallow_signup is the flag to disallow signup.
bool
disallow_signup
=
2
;
bool
disallow_signup
=
1
;
// disallow_password_login is the flag to disallow password login.
// disallow_password_login is the flag to disallow password login.
bool
disallow_password_login
=
3
;
bool
disallow_password_login
=
2
;
// additional_script is the additional script.
// additional_script is the additional script.
string
additional_script
=
4
;
string
additional_script
=
3
;
// additional_style is the additional style.
// additional_style is the additional style.
string
additional_style
=
5
;
string
additional_style
=
4
;
// custom_profile is the custom profile.
// custom_profile is the custom profile.
WorkspaceCustomProfile
custom_profile
=
6
;
WorkspaceCustomProfile
custom_profile
=
5
;
}
}
message
WorkspaceCustomProfile
{
message
WorkspaceCustomProfile
{
...
...
server/router/api/v1/workspace_setting_service.go
View file @
b2154266
...
@@ -121,7 +121,6 @@ func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSe
...
@@ -121,7 +121,6 @@ func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSe
return
nil
return
nil
}
}
generalSetting
:=
&
v1pb
.
WorkspaceGeneralSetting
{
generalSetting
:=
&
v1pb
.
WorkspaceGeneralSetting
{
InstanceUrl
:
setting
.
InstanceUrl
,
DisallowSignup
:
setting
.
DisallowSignup
,
DisallowSignup
:
setting
.
DisallowSignup
,
DisallowPasswordLogin
:
setting
.
DisallowPasswordLogin
,
DisallowPasswordLogin
:
setting
.
DisallowPasswordLogin
,
AdditionalScript
:
setting
.
AdditionalScript
,
AdditionalScript
:
setting
.
AdditionalScript
,
...
@@ -144,7 +143,6 @@ func convertWorkspaceGeneralSettingToStore(setting *v1pb.WorkspaceGeneralSetting
...
@@ -144,7 +143,6 @@ func convertWorkspaceGeneralSettingToStore(setting *v1pb.WorkspaceGeneralSetting
return
nil
return
nil
}
}
generalSetting
:=
&
storepb
.
WorkspaceGeneralSetting
{
generalSetting
:=
&
storepb
.
WorkspaceGeneralSetting
{
InstanceUrl
:
setting
.
InstanceUrl
,
DisallowSignup
:
setting
.
DisallowSignup
,
DisallowSignup
:
setting
.
DisallowSignup
,
DisallowPasswordLogin
:
setting
.
DisallowPasswordLogin
,
DisallowPasswordLogin
:
setting
.
DisallowPasswordLogin
,
AdditionalScript
:
setting
.
AdditionalScript
,
AdditionalScript
:
setting
.
AdditionalScript
,
...
...
server/router/frontend/frontend.go
View file @
b2154266
...
@@ -3,16 +3,11 @@ package frontend
...
@@ -3,16 +3,11 @@ package frontend
import
(
import
(
"context"
"context"
"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/gomark/parser"
"github.com/yourselfhosted/gomark/parser/tokenizer"
"github.com/yourselfhosted/gomark/renderer"
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/server/profile"
"github.com/usememos/memos/server/profile"
...
@@ -22,11 +17,6 @@ import (
...
@@ -22,11 +17,6 @@ import (
//go:embed dist
//go:embed dist
var
embeddedFiles
embed
.
FS
var
embeddedFiles
embed
.
FS
const
(
// maxMetadataDescriptionLength is the maximum length of metadata description.
maxMetadataDescriptionLength
=
256
)
type
FrontendService
struct
{
type
FrontendService
struct
{
Profile
*
profile
.
Profile
Profile
*
profile
.
Profile
Store
*
store
.
Store
Store
*
store
.
Store
...
@@ -41,7 +31,7 @@ func NewFrontendService(profile *profile.Profile, store *store.Store) *FrontendS
...
@@ -41,7 +31,7 @@ func NewFrontendService(profile *profile.Profile, store *store.Store) *FrontendS
func
(
s
*
FrontendService
)
Serve
(
ctx
context
.
Context
,
e
*
echo
.
Echo
)
{
func
(
s
*
FrontendService
)
Serve
(
ctx
context
.
Context
,
e
*
echo
.
Echo
)
{
skipper
:=
func
(
c
echo
.
Context
)
bool
{
skipper
:=
func
(
c
echo
.
Context
)
bool
{
return
util
.
HasPrefixes
(
c
.
Path
(),
"/
o"
,
"/api"
,
"/memos.api.v1"
,
"/robots.txt"
,
"/sitemap.xml"
,
"/m/:name
"
)
return
util
.
HasPrefixes
(
c
.
Path
(),
"/
api"
,
"/memos.api.v1
"
)
}
}
// Use echo static middleware to serve the built dist folder.
// Use echo static middleware to serve the built dist folder.
...
@@ -51,89 +41,18 @@ func (s *FrontendService) Serve(ctx context.Context, e *echo.Echo) {
...
@@ -51,89 +41,18 @@ func (s *FrontendService) Serve(ctx context.Context, e *echo.Echo) {
Filesystem
:
getFileSystem
(
"dist"
),
Filesystem
:
getFileSystem
(
"dist"
),
Skipper
:
skipper
,
Skipper
:
skipper
,
}))
}))
g
:=
e
.
Group
(
"assets"
)
// Use echo gzip middleware to compress the response.
// Use echo gzip middleware to compress the response.
// Reference: https://echo.labstack.com/docs/middleware/gzip
// Reference: https://echo.labstack.com/docs/middleware/gzip
g
.
Use
(
middleware
.
GzipWithConfig
(
middleware
.
GzipConfig
{
e
.
Group
(
"assets"
)
.
Use
(
middleware
.
GzipWithConfig
(
middleware
.
GzipConfig
{
Level
:
5
,
Level
:
5
,
}))
}),
func
(
next
echo
.
HandlerFunc
)
echo
.
HandlerFunc
{
g
.
Use
(
func
(
next
echo
.
HandlerFunc
)
echo
.
HandlerFunc
{
return
func
(
c
echo
.
Context
)
error
{
return
func
(
c
echo
.
Context
)
error
{
c
.
Response
()
.
Header
()
.
Set
(
echo
.
HeaderCacheControl
,
"max-age=31536000, immutable"
)
c
.
Response
()
.
Header
()
.
Set
(
echo
.
HeaderCacheControl
,
"max-age=31536000, immutable"
)
return
next
(
c
)
return
next
(
c
)
}
}
})
},
middleware
.
StaticWithConfig
(
middleware
.
StaticConfig
{
g
.
Use
(
middleware
.
StaticWithConfig
(
middleware
.
StaticConfig
{
Filesystem
:
getFileSystem
(
"dist/assets"
),
Filesystem
:
getFileSystem
(
"dist/assets"
),
}))
}))
s
.
registerRoutes
(
e
)
s
.
registerFileRoutes
(
ctx
,
e
)
}
func
(
s
*
FrontendService
)
registerRoutes
(
e
*
echo
.
Echo
)
{
rawIndexHTML
:=
getRawIndexHTML
()
e
.
GET
(
"/m/:uid"
,
func
(
c
echo
.
Context
)
error
{
ctx
:=
c
.
Request
()
.
Context
()
uid
:=
c
.
Param
(
"uid"
)
memo
,
err
:=
s
.
Store
.
GetMemo
(
ctx
,
&
store
.
FindMemo
{
UID
:
&
uid
,
})
if
err
!=
nil
{
return
c
.
HTML
(
http
.
StatusOK
,
rawIndexHTML
)
}
if
memo
==
nil
{
return
c
.
HTML
(
http
.
StatusOK
,
rawIndexHTML
)
}
creator
,
err
:=
s
.
Store
.
GetUser
(
ctx
,
&
store
.
FindUser
{
ID
:
&
memo
.
CreatorID
,
})
if
err
!=
nil
{
return
c
.
HTML
(
http
.
StatusOK
,
rawIndexHTML
)
}
// Inject memo metadata into `index.html`.
indexHTML
:=
strings
.
ReplaceAll
(
rawIndexHTML
,
"<!-- memos.metadata.head -->"
,
generateMemoMetadata
(
memo
,
creator
)
.
String
())
indexHTML
=
strings
.
ReplaceAll
(
indexHTML
,
"<!-- memos.metadata.body -->"
,
fmt
.
Sprintf
(
"<!-- memos.memo.%d -->"
,
memo
.
ID
))
return
c
.
HTML
(
http
.
StatusOK
,
indexHTML
)
})
}
func
(
s
*
FrontendService
)
registerFileRoutes
(
ctx
context
.
Context
,
e
*
echo
.
Echo
)
{
workspaceGeneralSetting
,
err
:=
s
.
Store
.
GetWorkspaceGeneralSetting
(
ctx
)
if
err
!=
nil
{
return
}
instanceURL
:=
workspaceGeneralSetting
.
GetInstanceUrl
()
if
instanceURL
==
""
{
return
}
e
.
GET
(
"/robots.txt"
,
func
(
c
echo
.
Context
)
error
{
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
()
urlsets
:=
[]
string
{}
// Append memo list.
memoList
,
err
:=
s
.
Store
.
ListMemos
(
ctx
,
&
store
.
FindMemo
{
VisibilityList
:
[]
store
.
Visibility
{
store
.
Public
},
})
if
err
!=
nil
{
return
err
}
for
_
,
memo
:=
range
memoList
{
urlsets
=
append
(
urlsets
,
fmt
.
Sprintf
(
`<url><loc>%s</loc></url>`
,
fmt
.
Sprintf
(
"%s/m/%s"
,
instanceURL
,
memo
.
UID
)))
}
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
))
})
}
}
func
getFileSystem
(
path
string
)
http
.
FileSystem
{
func
getFileSystem
(
path
string
)
http
.
FileSystem
{
...
@@ -141,61 +60,5 @@ func getFileSystem(path string) http.FileSystem {
...
@@ -141,61 +60,5 @@ func getFileSystem(path string) http.FileSystem {
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
panic
(
err
)
}
}
return
http
.
FS
(
fs
)
return
http
.
FS
(
fs
)
}
}
func
generateMemoMetadata
(
memo
*
store
.
Memo
,
creator
*
store
.
User
)
*
Metadata
{
metadata
:=
getDefaultMetadata
()
metadata
.
Title
=
fmt
.
Sprintf
(
"%s(@%s) on Memos"
,
creator
.
Nickname
,
creator
.
Username
)
if
memo
.
Visibility
==
store
.
Public
{
tokens
:=
tokenizer
.
Tokenize
(
memo
.
Content
)
nodes
,
_
:=
parser
.
Parse
(
tokens
)
description
:=
renderer
.
NewStringRenderer
()
.
Render
(
nodes
)
if
len
(
description
)
==
0
{
description
=
memo
.
Content
}
if
len
(
description
)
>
maxMetadataDescriptionLength
{
description
=
description
[
:
maxMetadataDescriptionLength
]
+
"..."
}
metadata
.
Description
=
description
}
return
metadata
}
func
getRawIndexHTML
()
string
{
bytes
,
_
:=
embeddedFiles
.
ReadFile
(
"dist/index.html"
)
return
string
(
bytes
)
}
type
Metadata
struct
{
Title
string
Description
string
ImageURL
string
}
func
getDefaultMetadata
()
*
Metadata
{
return
&
Metadata
{
Title
:
"Memos"
,
Description
:
"A privacy-first, lightweight note-taking service. Easily capture and share your great thoughts."
,
ImageURL
:
"/logo.webp"
,
}
}
func
(
m
*
Metadata
)
String
()
string
{
metadataList
:=
[]
string
{
fmt
.
Sprintf
(
`<meta name="description" content="%s" />`
,
m
.
Description
),
fmt
.
Sprintf
(
`<meta property="og:title" content="%s" />`
,
m
.
Title
),
fmt
.
Sprintf
(
`<meta property="og:description" content="%s" />`
,
m
.
Description
),
fmt
.
Sprintf
(
`<meta property="og:image" content="%s" />`
,
m
.
ImageURL
),
`<meta property="og:type" content="website" />`
,
// Twitter related fields.
fmt
.
Sprintf
(
`<meta property="twitter:title" content="%s" />`
,
m
.
Title
),
fmt
.
Sprintf
(
`<meta property="twitter:description" content="%s" />`
,
m
.
Description
),
fmt
.
Sprintf
(
`<meta property="twitter:image" content="%s" />`
,
m
.
ImageURL
),
`<meta name="twitter:card" content="summary" />`
,
`<meta name="twitter:creator" content="memos" />`
,
}
return
strings
.
Join
(
metadataList
,
"
\n
"
)
}
web/src/components/Settings/WorkspaceSection.tsx
View file @
b2154266
...
@@ -64,26 +64,6 @@ const WorkspaceSection = () => {
...
@@ -64,26 +64,6 @@ const WorkspaceSection = () => {
showUpdateCustomizedProfileDialog
();
showUpdateCustomizedProfileDialog
();
};
};
const
handleInstanceUrlChanged
=
(
value
:
string
)
=>
{
setWorkspaceGeneralSetting
({
...
workspaceGeneralSetting
,
instanceUrl
:
value
});
};
const
handleSaveInstanceUrl
=
async
()
=>
{
try
{
await
workspaceSettingServiceClient
.
setWorkspaceSetting
({
setting
:
{
name
:
`
${
WorkspaceSettingPrefix
}${
WorkspaceSettingKey
.
GENERAL
}
`
,
generalSetting
:
workspaceGeneralSetting
,
},
});
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toast
.
error
(
error
.
response
.
data
.
message
);
return
;
}
toast
.
success
(
"Instance URL updated"
);
};
const
handleAdditionalStyleChanged
=
(
value
:
string
)
=>
{
const
handleAdditionalStyleChanged
=
(
value
:
string
)
=>
{
setWorkspaceGeneralSetting
({
...
workspaceGeneralSetting
,
additionalStyle
:
value
});
setWorkspaceGeneralSetting
({
...
workspaceGeneralSetting
,
additionalStyle
:
value
});
};
};
...
@@ -196,34 +176,6 @@ const WorkspaceSection = () => {
...
@@ -196,34 +176,6 @@ const WorkspaceSection = () => {
onChange=
{
(
event
)
=>
handleDisablePasswordLoginChanged
(
event
.
target
.
checked
)
}
onChange=
{
(
event
)
=>
handleDisablePasswordLoginChanged
(
event
.
target
.
checked
)
}
/>
/>
</
div
>
</
div
>
<
div
className=
"space-y-2 border rounded-md py-2 px-3 dark:border-zinc-700"
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
div
className=
"flex flex-row items-center"
>
<
div
className=
"w-auto flex items-center"
>
<
span
className=
"mr-1"
>
Instance URL
</
span
>
</
div
>
</
div
>
<
Button
variant=
"outlined"
color=
"neutral"
onClick=
{
handleSaveInstanceUrl
}
>
{
t
(
"common.save"
)
}
</
Button
>
</
div
>
<
Input
className=
"w-full"
placeholder=
{
"Should be started with http:// or https://"
}
value=
{
workspaceGeneralSetting
.
instanceUrl
}
onChange=
{
(
event
)
=>
handleInstanceUrlChanged
(
event
.
target
.
value
)
}
/>
<
div
className=
"w-full"
>
<
Link
className=
"text-gray-500 text-sm inline-flex flex-row justify-start items-center hover:underline hover:text-blue-600"
to=
"https://usememos.com/docs/advanced-settings/seo"
target=
"_blank"
>
{
t
(
"common.learn-more"
)
}
<
Icon
.
ExternalLink
className=
"inline w-4 h-auto ml-1"
/>
</
Link
>
</
div
>
</
div
>
<
div
className=
"space-y-2 border rounded-md py-2 px-3 dark:border-zinc-700"
>
<
div
className=
"space-y-2 border rounded-md py-2 px-3 dark:border-zinc-700"
>
<
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.system-section.additional-style"
)
}
</
span
>
<
span
>
{
t
(
"setting.system-section.additional-style"
)
}
</
span
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment