mirror of https://github.com/usememos/memos
chore: migrate user setting to api v1 package (#1855)
* chore: migrate to api v1 package * chore: updatepull/1856/head
parent
07e82c3f4a
commit
b44f2b5ffb
@ -0,0 +1,137 @@
|
||||
package v1
|
||||
|
||||
import "github.com/usememos/memos/server/profile"
|
||||
|
||||
// ActivityType is the type for an activity.
|
||||
type ActivityType string
|
||||
|
||||
const (
|
||||
// User related.
|
||||
|
||||
// ActivityUserCreate is the type for creating users.
|
||||
ActivityUserCreate ActivityType = "user.create"
|
||||
// ActivityUserUpdate is the type for updating users.
|
||||
ActivityUserUpdate ActivityType = "user.update"
|
||||
// ActivityUserDelete is the type for deleting users.
|
||||
ActivityUserDelete ActivityType = "user.delete"
|
||||
// ActivityUserAuthSignIn is the type for user signin.
|
||||
ActivityUserAuthSignIn ActivityType = "user.auth.signin"
|
||||
// ActivityUserAuthSignUp is the type for user signup.
|
||||
ActivityUserAuthSignUp ActivityType = "user.auth.signup"
|
||||
// ActivityUserSettingUpdate is the type for updating user settings.
|
||||
ActivityUserSettingUpdate ActivityType = "user.setting.update"
|
||||
|
||||
// Memo related.
|
||||
|
||||
// ActivityMemoCreate is the type for creating memos.
|
||||
ActivityMemoCreate ActivityType = "memo.create"
|
||||
// ActivityMemoUpdate is the type for updating memos.
|
||||
ActivityMemoUpdate ActivityType = "memo.update"
|
||||
// ActivityMemoDelete is the type for deleting memos.
|
||||
ActivityMemoDelete ActivityType = "memo.delete"
|
||||
|
||||
// Shortcut related.
|
||||
|
||||
// ActivityShortcutCreate is the type for creating shortcuts.
|
||||
ActivityShortcutCreate ActivityType = "shortcut.create"
|
||||
// ActivityShortcutUpdate is the type for updating shortcuts.
|
||||
ActivityShortcutUpdate ActivityType = "shortcut.update"
|
||||
// ActivityShortcutDelete is the type for deleting shortcuts.
|
||||
ActivityShortcutDelete ActivityType = "shortcut.delete"
|
||||
|
||||
// Resource related.
|
||||
|
||||
// ActivityResourceCreate is the type for creating resources.
|
||||
ActivityResourceCreate ActivityType = "resource.create"
|
||||
// ActivityResourceDelete is the type for deleting resources.
|
||||
ActivityResourceDelete ActivityType = "resource.delete"
|
||||
|
||||
// Tag related.
|
||||
|
||||
// ActivityTagCreate is the type for creating tags.
|
||||
ActivityTagCreate ActivityType = "tag.create"
|
||||
// ActivityTagDelete is the type for deleting tags.
|
||||
ActivityTagDelete ActivityType = "tag.delete"
|
||||
|
||||
// Server related.
|
||||
|
||||
// ActivityServerStart is the type for starting server.
|
||||
ActivityServerStart ActivityType = "server.start"
|
||||
)
|
||||
|
||||
// ActivityLevel is the level of activities.
|
||||
type ActivityLevel string
|
||||
|
||||
const (
|
||||
// ActivityInfo is the INFO level of activities.
|
||||
ActivityInfo ActivityLevel = "INFO"
|
||||
// ActivityWarn is the WARN level of activities.
|
||||
ActivityWarn ActivityLevel = "WARN"
|
||||
// ActivityError is the ERROR level of activities.
|
||||
ActivityError ActivityLevel = "ERROR"
|
||||
)
|
||||
|
||||
type ActivityUserCreatePayload struct {
|
||||
UserID int `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Role Role `json:"role"`
|
||||
}
|
||||
|
||||
type ActivityUserAuthSignInPayload struct {
|
||||
UserID int `json:"userId"`
|
||||
IP string `json:"ip"`
|
||||
}
|
||||
|
||||
type ActivityUserAuthSignUpPayload struct {
|
||||
Username string `json:"username"`
|
||||
IP string `json:"ip"`
|
||||
}
|
||||
|
||||
type ActivityMemoCreatePayload struct {
|
||||
Content string `json:"content"`
|
||||
Visibility string `json:"visibility"`
|
||||
}
|
||||
|
||||
type ActivityShortcutCreatePayload struct {
|
||||
Title string `json:"title"`
|
||||
Payload string `json:"payload"`
|
||||
}
|
||||
|
||||
type ActivityResourceCreatePayload struct {
|
||||
Filename string `json:"filename"`
|
||||
Type string `json:"type"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
type ActivityTagCreatePayload struct {
|
||||
TagName string `json:"tagName"`
|
||||
}
|
||||
|
||||
type ActivityServerStartPayload struct {
|
||||
ServerID string `json:"serverId"`
|
||||
Profile *profile.Profile `json:"profile"`
|
||||
}
|
||||
|
||||
type Activity struct {
|
||||
ID int `json:"id"`
|
||||
|
||||
// Standard fields
|
||||
CreatorID int `json:"creatorId"`
|
||||
CreatedTs int64 `json:"createdTs"`
|
||||
|
||||
// Domain specific fields
|
||||
Type ActivityType `json:"type"`
|
||||
Level ActivityLevel `json:"level"`
|
||||
Payload string `json:"payload"`
|
||||
}
|
||||
|
||||
// ActivityCreate is the API message for creating an activity.
|
||||
type ActivityCreate struct {
|
||||
// Standard fields
|
||||
CreatorID int
|
||||
|
||||
// Domain specific fields
|
||||
Type ActivityType `json:"type"`
|
||||
Level ActivityLevel
|
||||
Payload string `json:"payload"`
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package v1
|
||||
|
||||
// Visibility is the type of a visibility.
|
||||
type Visibility string
|
||||
|
||||
const (
|
||||
// Public is the PUBLIC visibility.
|
||||
Public Visibility = "PUBLIC"
|
||||
// Protected is the PROTECTED visibility.
|
||||
Protected Visibility = "PROTECTED"
|
||||
// Private is the PRIVATE visibility.
|
||||
Private Visibility = "PRIVATE"
|
||||
)
|
||||
|
||||
func (v Visibility) String() string {
|
||||
switch v {
|
||||
case Public:
|
||||
return "PUBLIC"
|
||||
case Protected:
|
||||
return "PROTECTED"
|
||||
case Private:
|
||||
return "PRIVATE"
|
||||
}
|
||||
return "PRIVATE"
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SystemSettingName string
|
||||
|
||||
const (
|
||||
// SystemSettingServerIDName is the name of server id.
|
||||
SystemSettingServerIDName SystemSettingName = "server-id"
|
||||
// SystemSettingSecretSessionName is the name of secret session.
|
||||
SystemSettingSecretSessionName SystemSettingName = "secret-session"
|
||||
// SystemSettingAllowSignUpName is the name of allow signup setting.
|
||||
SystemSettingAllowSignUpName SystemSettingName = "allow-signup"
|
||||
// SystemSettingDisablePublicMemosName is the name of disable public memos setting.
|
||||
SystemSettingDisablePublicMemosName SystemSettingName = "disable-public-memos"
|
||||
// SystemSettingMaxUploadSizeMiBName is the name of max upload size setting.
|
||||
SystemSettingMaxUploadSizeMiBName SystemSettingName = "max-upload-size-mib"
|
||||
// SystemSettingAdditionalStyleName is the name of additional style.
|
||||
SystemSettingAdditionalStyleName SystemSettingName = "additional-style"
|
||||
// SystemSettingAdditionalScriptName is the name of additional script.
|
||||
SystemSettingAdditionalScriptName SystemSettingName = "additional-script"
|
||||
// SystemSettingCustomizedProfileName is the name of customized server profile.
|
||||
SystemSettingCustomizedProfileName SystemSettingName = "customized-profile"
|
||||
// SystemSettingStorageServiceIDName is the name of storage service ID.
|
||||
SystemSettingStorageServiceIDName SystemSettingName = "storage-service-id"
|
||||
// SystemSettingLocalStoragePathName is the name of local storage path.
|
||||
SystemSettingLocalStoragePathName SystemSettingName = "local-storage-path"
|
||||
// SystemSettingOpenAIConfigName is the name of OpenAI config.
|
||||
SystemSettingOpenAIConfigName SystemSettingName = "openai-config"
|
||||
// SystemSettingTelegramBotToken is the name of Telegram Bot Token.
|
||||
SystemSettingTelegramBotTokenName SystemSettingName = "telegram-bot-token"
|
||||
SystemSettingMemoDisplayWithUpdatedTsName SystemSettingName = "memo-display-with-updated-ts"
|
||||
)
|
||||
|
||||
// CustomizedProfile is the struct definition for SystemSettingCustomizedProfileName system setting item.
|
||||
type CustomizedProfile struct {
|
||||
// Name is the server name, default is `memos`
|
||||
Name string `json:"name"`
|
||||
// LogoURL is the url of logo image.
|
||||
LogoURL string `json:"logoUrl"`
|
||||
// Description is the server description.
|
||||
Description string `json:"description"`
|
||||
// Locale is the server default locale.
|
||||
Locale string `json:"locale"`
|
||||
// Appearance is the server default appearance.
|
||||
Appearance string `json:"appearance"`
|
||||
// ExternalURL is the external url of server. e.g. https://usermemos.com
|
||||
ExternalURL string `json:"externalUrl"`
|
||||
}
|
||||
|
||||
type OpenAIConfig struct {
|
||||
Key string `json:"key"`
|
||||
Host string `json:"host"`
|
||||
}
|
||||
|
||||
func (key SystemSettingName) String() string {
|
||||
switch key {
|
||||
case SystemSettingServerIDName:
|
||||
return "server-id"
|
||||
case SystemSettingSecretSessionName:
|
||||
return "secret-session"
|
||||
case SystemSettingAllowSignUpName:
|
||||
return "allow-signup"
|
||||
case SystemSettingDisablePublicMemosName:
|
||||
return "disable-public-memos"
|
||||
case SystemSettingMaxUploadSizeMiBName:
|
||||
return "max-upload-size-mib"
|
||||
case SystemSettingAdditionalStyleName:
|
||||
return "additional-style"
|
||||
case SystemSettingAdditionalScriptName:
|
||||
return "additional-script"
|
||||
case SystemSettingCustomizedProfileName:
|
||||
return "customized-profile"
|
||||
case SystemSettingStorageServiceIDName:
|
||||
return "storage-service-id"
|
||||
case SystemSettingLocalStoragePathName:
|
||||
return "local-storage-path"
|
||||
case SystemSettingOpenAIConfigName:
|
||||
return "openai-config"
|
||||
case SystemSettingTelegramBotTokenName:
|
||||
return "telegram-bot-token"
|
||||
case SystemSettingMemoDisplayWithUpdatedTsName:
|
||||
return "memo-display-with-updated-ts"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SystemSetting struct {
|
||||
Name SystemSettingName `json:"name"`
|
||||
// Value is a JSON string with basic value.
|
||||
Value string `json:"value"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type SystemSettingUpsert struct {
|
||||
Name SystemSettingName `json:"name"`
|
||||
Value string `json:"value"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
const systemSettingUnmarshalError = `failed to unmarshal value from system setting "%v"`
|
||||
|
||||
func (upsert SystemSettingUpsert) Validate() error {
|
||||
switch settingName := upsert.Name; settingName {
|
||||
case SystemSettingServerIDName:
|
||||
return fmt.Errorf("updating %v is not allowed", settingName)
|
||||
case SystemSettingAllowSignUpName:
|
||||
var value bool
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingDisablePublicMemosName:
|
||||
var value bool
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingMaxUploadSizeMiBName:
|
||||
var value int
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingAdditionalStyleName:
|
||||
var value string
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingAdditionalScriptName:
|
||||
var value string
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingCustomizedProfileName:
|
||||
customizedProfile := CustomizedProfile{
|
||||
Name: "memos",
|
||||
LogoURL: "",
|
||||
Description: "",
|
||||
Locale: "en",
|
||||
Appearance: "system",
|
||||
ExternalURL: "",
|
||||
}
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &customizedProfile); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingStorageServiceIDName:
|
||||
// Note: 0 is the default value(database) for storage service ID.
|
||||
value := 0
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
return nil
|
||||
case SystemSettingLocalStoragePathName:
|
||||
value := ""
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingOpenAIConfigName:
|
||||
value := OpenAIConfig{}
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingTelegramBotTokenName:
|
||||
if upsert.Value == "" {
|
||||
return nil
|
||||
}
|
||||
// Bot Token with Reverse Proxy shoule like `http.../bot<token>`
|
||||
if strings.HasPrefix(upsert.Value, "http") {
|
||||
slashIndex := strings.LastIndexAny(upsert.Value, "/")
|
||||
if strings.HasPrefix(upsert.Value[slashIndex:], "/bot") {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("token start with `http` must end with `/bot<token>`")
|
||||
}
|
||||
fragments := strings.Split(upsert.Value, ":")
|
||||
if len(fragments) != 2 {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingMemoDisplayWithUpdatedTsName:
|
||||
var value bool
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid system setting name")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SystemSettingFind struct {
|
||||
Name SystemSettingName `json:"name"`
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type UserSettingKey string
|
||||
|
||||
const (
|
||||
// UserSettingLocaleKey is the key type for user locale.
|
||||
UserSettingLocaleKey UserSettingKey = "locale"
|
||||
// UserSettingAppearanceKey is the key type for user appearance.
|
||||
UserSettingAppearanceKey UserSettingKey = "appearance"
|
||||
// UserSettingMemoVisibilityKey is the key type for user preference memo default visibility.
|
||||
UserSettingMemoVisibilityKey UserSettingKey = "memo-visibility"
|
||||
// UserSettingTelegramUserID is the key type for telegram UserID of memos user.
|
||||
UserSettingTelegramUserIDKey UserSettingKey = "telegram-user-id"
|
||||
)
|
||||
|
||||
// String returns the string format of UserSettingKey type.
|
||||
func (key UserSettingKey) String() string {
|
||||
switch key {
|
||||
case UserSettingLocaleKey:
|
||||
return "locale"
|
||||
case UserSettingAppearanceKey:
|
||||
return "appearance"
|
||||
case UserSettingMemoVisibilityKey:
|
||||
return "memo-visibility"
|
||||
case UserSettingTelegramUserIDKey:
|
||||
return "telegram-user-id"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var (
|
||||
UserSettingLocaleValue = []string{
|
||||
"de",
|
||||
"en",
|
||||
"es",
|
||||
"fr",
|
||||
"hr",
|
||||
"it",
|
||||
"ja",
|
||||
"ko",
|
||||
"nl",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"ru",
|
||||
"sl",
|
||||
"sv",
|
||||
"tr",
|
||||
"uk",
|
||||
"vi",
|
||||
"zh-Hans",
|
||||
"zh-Hant",
|
||||
}
|
||||
UserSettingAppearanceValue = []string{"system", "light", "dark"}
|
||||
UserSettingMemoVisibilityValue = []Visibility{Private, Protected, Public}
|
||||
)
|
||||
|
||||
type UserSetting struct {
|
||||
UserID int
|
||||
Key UserSettingKey `json:"key"`
|
||||
// Value is a JSON string with basic value
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type UserSettingUpsert struct {
|
||||
UserID int `json:"-"`
|
||||
Key UserSettingKey `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (upsert UserSettingUpsert) Validate() error {
|
||||
if upsert.Key == UserSettingLocaleKey {
|
||||
localeValue := "en"
|
||||
err := json.Unmarshal([]byte(upsert.Value), &localeValue)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal user setting locale value")
|
||||
}
|
||||
if !slices.Contains(UserSettingLocaleValue, localeValue) {
|
||||
return fmt.Errorf("invalid user setting locale value")
|
||||
}
|
||||
} else if upsert.Key == UserSettingAppearanceKey {
|
||||
appearanceValue := "system"
|
||||
err := json.Unmarshal([]byte(upsert.Value), &appearanceValue)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal user setting appearance value")
|
||||
}
|
||||
if !slices.Contains(UserSettingAppearanceValue, appearanceValue) {
|
||||
return fmt.Errorf("invalid user setting appearance value")
|
||||
}
|
||||
} else if upsert.Key == UserSettingMemoVisibilityKey {
|
||||
memoVisibilityValue := Private
|
||||
err := json.Unmarshal([]byte(upsert.Value), &memoVisibilityValue)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal user setting memo visibility value")
|
||||
}
|
||||
if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) {
|
||||
return fmt.Errorf("invalid user setting memo visibility value")
|
||||
}
|
||||
} else if upsert.Key == UserSettingTelegramUserIDKey {
|
||||
var s string
|
||||
err := json.Unmarshal([]byte(upsert.Value), &s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid user setting telegram user id value")
|
||||
}
|
||||
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
if _, err := strconv.Atoi(s); err != nil {
|
||||
return fmt.Errorf("invalid user setting telegram user id value")
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("invalid user setting key")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type UserSettingFind struct {
|
||||
UserID *int
|
||||
|
||||
Key UserSettingKey `json:"key"`
|
||||
}
|
||||
|
||||
type UserSettingDelete struct {
|
||||
UserID int
|
||||
}
|
Loading…
Reference in New Issue