mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore: update golangci-lint config
This commit is contained in:
@ -1,5 +1,6 @@
|
|||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
|
- errcheck
|
||||||
- goimports
|
- goimports
|
||||||
- revive
|
- revive
|
||||||
- govet
|
- govet
|
||||||
@ -10,17 +11,30 @@ linters:
|
|||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- nilerr
|
- nilerr
|
||||||
- godot
|
- godot
|
||||||
|
- forbidigo
|
||||||
|
- mirror
|
||||||
|
- bodyclose
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
|
include:
|
||||||
|
# https://golangci-lint.run/usage/configuration/#command-line-options
|
||||||
exclude:
|
exclude:
|
||||||
- Rollback
|
- Rollback
|
||||||
|
- logger.Sync
|
||||||
|
- pgInstance.Stop
|
||||||
- fmt.Printf
|
- fmt.Printf
|
||||||
- fmt.Print
|
- Enter(.*)_(.*)
|
||||||
|
- Exit(.*)_(.*)
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
|
goimports:
|
||||||
|
# Put imports beginning with prefix after 3rd-party packages.
|
||||||
|
local-prefixes: github.com/usememos/memos
|
||||||
revive:
|
revive:
|
||||||
|
# Default to run all linters so that new rules in the future could automatically be added to the static check.
|
||||||
enable-all-rules: true
|
enable-all-rules: true
|
||||||
rules:
|
rules:
|
||||||
|
# The following rules are too strict and make coding harder. We do not enable them for now.
|
||||||
- name: file-header
|
- name: file-header
|
||||||
disabled: true
|
disabled: true
|
||||||
- name: line-length-limit
|
- name: line-length-limit
|
||||||
@ -56,9 +70,14 @@ linters-settings:
|
|||||||
- ifElseChain
|
- ifElseChain
|
||||||
govet:
|
govet:
|
||||||
settings:
|
settings:
|
||||||
printf:
|
printf: # The name of the analyzer, run `go tool vet help` to see the list of all analyzers
|
||||||
funcs:
|
funcs: # Run `go tool vet help printf` to see the full configuration of `printf`.
|
||||||
- common.Errorf
|
- common.Errorf
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
- fieldalignment
|
||||||
|
- shadow
|
||||||
forbidigo:
|
forbidigo:
|
||||||
forbid:
|
forbid:
|
||||||
- 'fmt\.Errorf(# Please use errors\.Wrap\|Wrapf\|Errorf instead)?'
|
- 'fmt\.Errorf(# Please use errors\.Wrap\|Wrapf\|Errorf instead)?'
|
||||||
|
- 'ioutil\.ReadDir(# Please use os\.ReadDir)?'
|
||||||
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -2,8 +2,4 @@
|
|||||||
"json.schemaDownload.enable":true,
|
"json.schemaDownload.enable":true,
|
||||||
"go.lintOnSave": "workspace",
|
"go.lintOnSave": "workspace",
|
||||||
"go.lintTool": "golangci-lint",
|
"go.lintTool": "golangci-lint",
|
||||||
"go.inferGopath": false,
|
|
||||||
"go.toolsEnvVars": {
|
|
||||||
"GO111MODULE": "on"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,14 @@ import (
|
|||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
"github.com/usememos/memos/api/auth"
|
"github.com/usememos/memos/api/auth"
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/plugin/idp"
|
"github.com/usememos/memos/plugin/idp"
|
||||||
"github.com/usememos/memos/plugin/idp/oauth2"
|
"github.com/usememos/memos/plugin/idp/oauth2"
|
||||||
storepb "github.com/usememos/memos/proto/gen/store"
|
storepb "github.com/usememos/memos/proto/gen/store"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SignIn struct {
|
type SignIn struct {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
getter "github.com/usememos/memos/plugin/http-getter"
|
getter "github.com/usememos/memos/plugin/http-getter"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/usememos/memos/api/auth"
|
"github.com/usememos/memos/api/auth"
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
storepb "github.com/usememos/memos/proto/gen/store"
|
storepb "github.com/usememos/memos/proto/gen/store"
|
||||||
|
@ -10,10 +10,11 @@ import (
|
|||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/log"
|
"github.com/usememos/memos/common/log"
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Visibility is the type of a visibility.
|
// Visibility is the type of a visibility.
|
||||||
@ -336,17 +337,17 @@ func (s *APIV1Service) CreateMemo(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memo, err = s.Store.GetMemo(ctx, &store.FindMemo{
|
composedMemo, err := s.Store.GetMemo(ctx, &store.FindMemo{
|
||||||
ID: &memo.ID,
|
ID: &memo.ID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo").SetInternal(err)
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo").SetInternal(err)
|
||||||
}
|
}
|
||||||
if memo == nil {
|
if composedMemo == nil {
|
||||||
return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Memo not found: %d", memo.ID))
|
return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Memo not found: %d", memo.ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
memoResponse, err := s.convertMemoFromStore(ctx, memo)
|
memoResponse, err := s.convertMemoFromStore(ctx, composedMemo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
@ -20,11 +20,12 @@ import (
|
|||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/log"
|
"github.com/usememos/memos/common/log"
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/plugin/storage/s3"
|
"github.com/usememos/memos/plugin/storage/s3"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Resource struct {
|
type Resource struct {
|
||||||
@ -606,14 +607,14 @@ func convertResourceFromStore(resource *store.Resource) *Resource {
|
|||||||
func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resource, r io.Reader) error {
|
func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resource, r io.Reader) error {
|
||||||
systemSettingStorageServiceID, err := s.GetSystemSetting(ctx, &store.FindSystemSetting{Name: SystemSettingStorageServiceIDName.String()})
|
systemSettingStorageServiceID, err := s.GetSystemSetting(ctx, &store.FindSystemSetting{Name: SystemSettingStorageServiceIDName.String()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to find SystemSettingStorageServiceIDName: %s", err)
|
return errors.Errorf("Failed to find SystemSettingStorageServiceIDName: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
storageServiceID := LocalStorage
|
storageServiceID := LocalStorage
|
||||||
if systemSettingStorageServiceID != nil {
|
if systemSettingStorageServiceID != nil {
|
||||||
err = json.Unmarshal([]byte(systemSettingStorageServiceID.Value), &storageServiceID)
|
err = json.Unmarshal([]byte(systemSettingStorageServiceID.Value), &storageServiceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to unmarshal storage service id: %s", err)
|
return errors.Errorf("Failed to unmarshal storage service id: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,7 +622,7 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc
|
|||||||
if storageServiceID == DatabaseStorage {
|
if storageServiceID == DatabaseStorage {
|
||||||
fileBytes, err := io.ReadAll(r)
|
fileBytes, err := io.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to read file: %s", err)
|
return errors.Errorf("Failed to read file: %s", err)
|
||||||
}
|
}
|
||||||
create.Blob = fileBytes
|
create.Blob = fileBytes
|
||||||
return nil
|
return nil
|
||||||
@ -629,13 +630,13 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc
|
|||||||
// `LocalStorage` means save blob into local disk
|
// `LocalStorage` means save blob into local disk
|
||||||
systemSettingLocalStoragePath, err := s.GetSystemSetting(ctx, &store.FindSystemSetting{Name: SystemSettingLocalStoragePathName.String()})
|
systemSettingLocalStoragePath, err := s.GetSystemSetting(ctx, &store.FindSystemSetting{Name: SystemSettingLocalStoragePathName.String()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to find SystemSettingLocalStoragePathName: %s", err)
|
return errors.Errorf("Failed to find SystemSettingLocalStoragePathName: %s", err)
|
||||||
}
|
}
|
||||||
localStoragePath := "assets/{timestamp}_{filename}"
|
localStoragePath := "assets/{timestamp}_{filename}"
|
||||||
if systemSettingLocalStoragePath != nil && systemSettingLocalStoragePath.Value != "" {
|
if systemSettingLocalStoragePath != nil && systemSettingLocalStoragePath.Value != "" {
|
||||||
err = json.Unmarshal([]byte(systemSettingLocalStoragePath.Value), &localStoragePath)
|
err = json.Unmarshal([]byte(systemSettingLocalStoragePath.Value), &localStoragePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to unmarshal SystemSettingLocalStoragePathName: %s", err)
|
return errors.Errorf("Failed to unmarshal SystemSettingLocalStoragePathName: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filePath := filepath.FromSlash(localStoragePath)
|
filePath := filepath.FromSlash(localStoragePath)
|
||||||
@ -646,16 +647,16 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc
|
|||||||
|
|
||||||
dir := filepath.Dir(filePath)
|
dir := filepath.Dir(filePath)
|
||||||
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
|
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||||
return fmt.Errorf("Failed to create directory: %s", err)
|
return errors.Errorf("Failed to create directory: %s", err)
|
||||||
}
|
}
|
||||||
dst, err := os.Create(filePath)
|
dst, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create file: %s", err)
|
return errors.Errorf("Failed to create file: %s", err)
|
||||||
}
|
}
|
||||||
defer dst.Close()
|
defer dst.Close()
|
||||||
_, err = io.Copy(dst, r)
|
_, err = io.Copy(dst, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to copy file: %s", err)
|
return errors.Errorf("Failed to copy file: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
create.InternalPath = filePath
|
create.InternalPath = filePath
|
||||||
@ -665,18 +666,18 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc
|
|||||||
// Others: store blob into external service, such as S3
|
// Others: store blob into external service, such as S3
|
||||||
storage, err := s.GetStorage(ctx, &store.FindStorage{ID: &storageServiceID})
|
storage, err := s.GetStorage(ctx, &store.FindStorage{ID: &storageServiceID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to find StorageServiceID: %s", err)
|
return errors.Errorf("Failed to find StorageServiceID: %s", err)
|
||||||
}
|
}
|
||||||
if storage == nil {
|
if storage == nil {
|
||||||
return fmt.Errorf("Storage %d not found", storageServiceID)
|
return errors.Errorf("Storage %d not found", storageServiceID)
|
||||||
}
|
}
|
||||||
storageMessage, err := ConvertStorageFromStore(storage)
|
storageMessage, err := ConvertStorageFromStore(storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to ConvertStorageFromStore: %s", err)
|
return errors.Errorf("Failed to ConvertStorageFromStore: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if storageMessage.Type != StorageS3 {
|
if storageMessage.Type != StorageS3 {
|
||||||
return fmt.Errorf("Unsupported storage type: %s", storageMessage.Type)
|
return errors.Errorf("Unsupported storage type: %s", storageMessage.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
s3Config := storageMessage.Config.S3Config
|
s3Config := storageMessage.Config.S3Config
|
||||||
@ -690,7 +691,7 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc
|
|||||||
URLSuffix: s3Config.URLSuffix,
|
URLSuffix: s3Config.URLSuffix,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create s3 client: %s", err)
|
return errors.Errorf("Failed to create s3 client: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filePath := s3Config.Path
|
filePath := s3Config.Path
|
||||||
@ -701,7 +702,7 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc
|
|||||||
|
|
||||||
link, err := s3Client.UploadFile(ctx, filePath, create.Type, r)
|
link, err := s3Client.UploadFile(ctx, filePath, create.Type, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to upload via s3 client: %s", err)
|
return errors.Errorf("Failed to upload via s3 client: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
create.ExternalLink = link
|
create.ExternalLink = link
|
||||||
|
@ -12,9 +12,11 @@ import (
|
|||||||
|
|
||||||
"github.com/gorilla/feeds"
|
"github.com/gorilla/feeds"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/yuin/goldmark"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"github.com/yuin/goldmark"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxRSSItemCount = 100
|
const maxRSSItemCount = 100
|
||||||
@ -129,7 +131,7 @@ func (s *APIV1Service) generateRSSFromMemoList(ctx context.Context, memoList []*
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if resource == nil {
|
if resource == nil {
|
||||||
return "", fmt.Errorf("Resource not found: %d", resourceID)
|
return "", errors.Errorf("Resource not found: %d", resourceID)
|
||||||
}
|
}
|
||||||
enclosure := feeds.Enclosure{}
|
enclosure := feeds.Enclosure{}
|
||||||
if resource.ExternalLink != "" {
|
if resource.ExternalLink != "" {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
@ -5,10 +5,11 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/log"
|
"github.com/usememos/memos/common/log"
|
||||||
"github.com/usememos/memos/server/profile"
|
"github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SystemStatus struct {
|
type SystemStatus struct {
|
||||||
|
@ -2,11 +2,12 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -186,36 +187,36 @@ func (s *APIV1Service) CreateSystemSetting(c echo.Context) error {
|
|||||||
func (upsert UpsertSystemSettingRequest) Validate() error {
|
func (upsert UpsertSystemSettingRequest) Validate() error {
|
||||||
switch settingName := upsert.Name; settingName {
|
switch settingName := upsert.Name; settingName {
|
||||||
case SystemSettingServerIDName:
|
case SystemSettingServerIDName:
|
||||||
return fmt.Errorf("updating %v is not allowed", settingName)
|
return errors.Errorf("updating %v is not allowed", settingName)
|
||||||
case SystemSettingAllowSignUpName:
|
case SystemSettingAllowSignUpName:
|
||||||
var value bool
|
var value bool
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingDisablePasswordLoginName:
|
case SystemSettingDisablePasswordLoginName:
|
||||||
var value bool
|
var value bool
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingDisablePublicMemosName:
|
case SystemSettingDisablePublicMemosName:
|
||||||
var value bool
|
var value bool
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingMaxUploadSizeMiBName:
|
case SystemSettingMaxUploadSizeMiBName:
|
||||||
var value int
|
var value int
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingAdditionalStyleName:
|
case SystemSettingAdditionalStyleName:
|
||||||
var value string
|
var value string
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingAdditionalScriptName:
|
case SystemSettingAdditionalScriptName:
|
||||||
var value string
|
var value string
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingCustomizedProfileName:
|
case SystemSettingCustomizedProfileName:
|
||||||
customizedProfile := CustomizedProfile{
|
customizedProfile := CustomizedProfile{
|
||||||
@ -227,27 +228,27 @@ func (upsert UpsertSystemSettingRequest) Validate() error {
|
|||||||
ExternalURL: "",
|
ExternalURL: "",
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &customizedProfile); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &customizedProfile); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingStorageServiceIDName:
|
case SystemSettingStorageServiceIDName:
|
||||||
// Note: 0 is the default value(database) for storage service ID.
|
// Note: 0 is the default value(database) for storage service ID.
|
||||||
value := 0
|
value := 0
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case SystemSettingLocalStoragePathName:
|
case SystemSettingLocalStoragePathName:
|
||||||
value := ""
|
value := ""
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingAutoBackupIntervalName:
|
case SystemSettingAutoBackupIntervalName:
|
||||||
var value int
|
var value int
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
if value < 0 {
|
if value < 0 {
|
||||||
return fmt.Errorf("must be positive")
|
return errors.Errorf("must be positive")
|
||||||
}
|
}
|
||||||
case SystemSettingTelegramBotTokenName:
|
case SystemSettingTelegramBotTokenName:
|
||||||
if upsert.Value == "" {
|
if upsert.Value == "" {
|
||||||
@ -259,19 +260,19 @@ func (upsert UpsertSystemSettingRequest) Validate() error {
|
|||||||
if strings.HasPrefix(upsert.Value[slashIndex:], "/bot") {
|
if strings.HasPrefix(upsert.Value[slashIndex:], "/bot") {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("token start with `http` must end with `/bot<token>`")
|
return errors.Errorf("token start with `http` must end with `/bot<token>`")
|
||||||
}
|
}
|
||||||
fragments := strings.Split(upsert.Value, ":")
|
fragments := strings.Split(upsert.Value, ":")
|
||||||
if len(fragments) != 2 {
|
if len(fragments) != 2 {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
case SystemSettingMemoDisplayWithUpdatedTsName:
|
case SystemSettingMemoDisplayWithUpdatedTsName:
|
||||||
var value bool
|
var value bool
|
||||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||||
return fmt.Errorf(systemSettingUnmarshalError, settingName)
|
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid system setting name")
|
return errors.Errorf("invalid system setting name")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,9 @@ import (
|
|||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Tag struct {
|
type Tag struct {
|
||||||
|
@ -8,9 +8,10 @@ import (
|
|||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Role is the type of a role.
|
// Role is the type of a role.
|
||||||
@ -404,26 +405,26 @@ func (s *APIV1Service) UpdateUser(c echo.Context) error {
|
|||||||
|
|
||||||
func (create CreateUserRequest) Validate() error {
|
func (create CreateUserRequest) Validate() error {
|
||||||
if len(create.Username) < 3 {
|
if len(create.Username) < 3 {
|
||||||
return fmt.Errorf("username is too short, minimum length is 3")
|
return errors.Errorf("username is too short, minimum length is 3")
|
||||||
}
|
}
|
||||||
if len(create.Username) > 32 {
|
if len(create.Username) > 32 {
|
||||||
return fmt.Errorf("username is too long, maximum length is 32")
|
return errors.Errorf("username is too long, maximum length is 32")
|
||||||
}
|
}
|
||||||
if len(create.Password) < 3 {
|
if len(create.Password) < 3 {
|
||||||
return fmt.Errorf("password is too short, minimum length is 3")
|
return errors.Errorf("password is too short, minimum length is 3")
|
||||||
}
|
}
|
||||||
if len(create.Password) > 512 {
|
if len(create.Password) > 512 {
|
||||||
return fmt.Errorf("password is too long, maximum length is 512")
|
return errors.Errorf("password is too long, maximum length is 512")
|
||||||
}
|
}
|
||||||
if len(create.Nickname) > 64 {
|
if len(create.Nickname) > 64 {
|
||||||
return fmt.Errorf("nickname is too long, maximum length is 64")
|
return errors.Errorf("nickname is too long, maximum length is 64")
|
||||||
}
|
}
|
||||||
if create.Email != "" {
|
if create.Email != "" {
|
||||||
if len(create.Email) > 256 {
|
if len(create.Email) > 256 {
|
||||||
return fmt.Errorf("email is too long, maximum length is 256")
|
return errors.Errorf("email is too long, maximum length is 256")
|
||||||
}
|
}
|
||||||
if !util.ValidateEmail(create.Email) {
|
if !util.ValidateEmail(create.Email) {
|
||||||
return fmt.Errorf("invalid email format")
|
return errors.Errorf("invalid email format")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,31 +433,31 @@ func (create CreateUserRequest) Validate() error {
|
|||||||
|
|
||||||
func (update UpdateUserRequest) Validate() error {
|
func (update UpdateUserRequest) Validate() error {
|
||||||
if update.Username != nil && len(*update.Username) < 3 {
|
if update.Username != nil && len(*update.Username) < 3 {
|
||||||
return fmt.Errorf("username is too short, minimum length is 3")
|
return errors.Errorf("username is too short, minimum length is 3")
|
||||||
}
|
}
|
||||||
if update.Username != nil && len(*update.Username) > 32 {
|
if update.Username != nil && len(*update.Username) > 32 {
|
||||||
return fmt.Errorf("username is too long, maximum length is 32")
|
return errors.Errorf("username is too long, maximum length is 32")
|
||||||
}
|
}
|
||||||
if update.Password != nil && len(*update.Password) < 3 {
|
if update.Password != nil && len(*update.Password) < 3 {
|
||||||
return fmt.Errorf("password is too short, minimum length is 3")
|
return errors.Errorf("password is too short, minimum length is 3")
|
||||||
}
|
}
|
||||||
if update.Password != nil && len(*update.Password) > 512 {
|
if update.Password != nil && len(*update.Password) > 512 {
|
||||||
return fmt.Errorf("password is too long, maximum length is 512")
|
return errors.Errorf("password is too long, maximum length is 512")
|
||||||
}
|
}
|
||||||
if update.Nickname != nil && len(*update.Nickname) > 64 {
|
if update.Nickname != nil && len(*update.Nickname) > 64 {
|
||||||
return fmt.Errorf("nickname is too long, maximum length is 64")
|
return errors.Errorf("nickname is too long, maximum length is 64")
|
||||||
}
|
}
|
||||||
if update.AvatarURL != nil {
|
if update.AvatarURL != nil {
|
||||||
if len(*update.AvatarURL) > 2<<20 {
|
if len(*update.AvatarURL) > 2<<20 {
|
||||||
return fmt.Errorf("avatar is too large, maximum is 2MB")
|
return errors.Errorf("avatar is too large, maximum is 2MB")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if update.Email != nil && *update.Email != "" {
|
if update.Email != nil && *update.Email != "" {
|
||||||
if len(*update.Email) > 256 {
|
if len(*update.Email) > 256 {
|
||||||
return fmt.Errorf("email is too long, maximum length is 256")
|
return errors.Errorf("email is too long, maximum length is 256")
|
||||||
}
|
}
|
||||||
if !util.ValidateEmail(*update.Email) {
|
if !util.ValidateEmail(*update.Email) {
|
||||||
return fmt.Errorf("invalid email format")
|
return errors.Errorf("invalid email format")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,13 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserSettingKey string
|
type UserSettingKey string
|
||||||
@ -127,37 +128,37 @@ func (upsert UpsertUserSettingRequest) Validate() error {
|
|||||||
localeValue := "en"
|
localeValue := "en"
|
||||||
err := json.Unmarshal([]byte(upsert.Value), &localeValue)
|
err := json.Unmarshal([]byte(upsert.Value), &localeValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal user setting locale value")
|
return errors.Errorf("failed to unmarshal user setting locale value")
|
||||||
}
|
}
|
||||||
if !slices.Contains(UserSettingLocaleValue, localeValue) {
|
if !slices.Contains(UserSettingLocaleValue, localeValue) {
|
||||||
return fmt.Errorf("invalid user setting locale value")
|
return errors.Errorf("invalid user setting locale value")
|
||||||
}
|
}
|
||||||
} else if upsert.Key == UserSettingAppearanceKey {
|
} else if upsert.Key == UserSettingAppearanceKey {
|
||||||
appearanceValue := "system"
|
appearanceValue := "system"
|
||||||
err := json.Unmarshal([]byte(upsert.Value), &appearanceValue)
|
err := json.Unmarshal([]byte(upsert.Value), &appearanceValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal user setting appearance value")
|
return errors.Errorf("failed to unmarshal user setting appearance value")
|
||||||
}
|
}
|
||||||
if !slices.Contains(UserSettingAppearanceValue, appearanceValue) {
|
if !slices.Contains(UserSettingAppearanceValue, appearanceValue) {
|
||||||
return fmt.Errorf("invalid user setting appearance value")
|
return errors.Errorf("invalid user setting appearance value")
|
||||||
}
|
}
|
||||||
} else if upsert.Key == UserSettingMemoVisibilityKey {
|
} else if upsert.Key == UserSettingMemoVisibilityKey {
|
||||||
memoVisibilityValue := Private
|
memoVisibilityValue := Private
|
||||||
err := json.Unmarshal([]byte(upsert.Value), &memoVisibilityValue)
|
err := json.Unmarshal([]byte(upsert.Value), &memoVisibilityValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal user setting memo visibility value")
|
return errors.Errorf("failed to unmarshal user setting memo visibility value")
|
||||||
}
|
}
|
||||||
if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) {
|
if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) {
|
||||||
return fmt.Errorf("invalid user setting memo visibility value")
|
return errors.Errorf("invalid user setting memo visibility value")
|
||||||
}
|
}
|
||||||
} else if upsert.Key == UserSettingTelegramUserIDKey {
|
} else if upsert.Key == UserSettingTelegramUserIDKey {
|
||||||
var key string
|
var key string
|
||||||
err := json.Unmarshal([]byte(upsert.Value), &key)
|
err := json.Unmarshal([]byte(upsert.Value), &key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid user setting telegram user id value")
|
return errors.Errorf("invalid user setting telegram user id value")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("invalid user setting key")
|
return errors.Errorf("invalid user setting key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -2,6 +2,7 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/telegram"
|
"github.com/usememos/memos/plugin/telegram"
|
||||||
"github.com/usememos/memos/server/profile"
|
"github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
|
@ -7,13 +7,14 @@ import (
|
|||||||
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/usememos/memos/api/auth"
|
|
||||||
storepb "github.com/usememos/memos/proto/gen/store"
|
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/api/auth"
|
||||||
|
storepb "github.com/usememos/memos/proto/gen/store"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContextKey is the key type of context value.
|
// ContextKey is the key type of context value.
|
||||||
|
@ -5,11 +5,12 @@ import (
|
|||||||
|
|
||||||
"github.com/google/cel-go/cel"
|
"github.com/google/cel-go/cel"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
v1alpha1 "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
v1alpha1 "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
|
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MemoService struct {
|
type MemoService struct {
|
||||||
|
@ -4,11 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
|
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResourceService struct {
|
type ResourceService struct {
|
||||||
|
@ -5,11 +5,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
||||||
"github.com/usememos/memos/server/profile"
|
"github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SystemService struct {
|
type SystemService struct {
|
||||||
|
@ -3,10 +3,11 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
|
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TagService struct {
|
type TagService struct {
|
||||||
|
@ -8,15 +8,16 @@ import (
|
|||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/usememos/memos/api/auth"
|
|
||||||
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
|
||||||
storepb "github.com/usememos/memos/proto/gen/store"
|
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/api/auth"
|
||||||
|
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
||||||
|
storepb "github.com/usememos/memos/proto/gen/store"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserService struct {
|
type UserService struct {
|
||||||
|
@ -7,12 +7,13 @@ import (
|
|||||||
grpcRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
grpcRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
|
||||||
"github.com/usememos/memos/server/profile"
|
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
"google.golang.org/grpc/reflection"
|
"google.golang.org/grpc/reflection"
|
||||||
|
|
||||||
|
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
||||||
|
"github.com/usememos/memos/server/profile"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type APIV2Service struct {
|
type APIV2Service struct {
|
||||||
|
11
cmd/memos.go
11
cmd/memos.go
@ -10,12 +10,13 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/log"
|
"github.com/usememos/memos/common/log"
|
||||||
"github.com/usememos/memos/server"
|
"github.com/usememos/memos/server"
|
||||||
_profile "github.com/usememos/memos/server/profile"
|
_profile "github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"github.com/usememos/memos/store/db"
|
"github.com/usememos/memos/store/db"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -144,15 +145,15 @@ func initConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func printGreetings() {
|
func printGreetings() {
|
||||||
fmt.Print(greetingBanner)
|
print(greetingBanner)
|
||||||
if len(profile.Addr) == 0 {
|
if len(profile.Addr) == 0 {
|
||||||
fmt.Printf("Version %s has been started on port %d\n", profile.Version, profile.Port)
|
fmt.Printf("Version %s has been started on port %d\n", profile.Version, profile.Port)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Version %s has been started on address '%s' and port %d\n", profile.Version, profile.Addr, profile.Port)
|
fmt.Printf("Version %s has been started on address '%s' and port %d\n", profile.Version, profile.Addr, profile.Port)
|
||||||
}
|
}
|
||||||
fmt.Println("---")
|
println("---")
|
||||||
fmt.Println("See more in:")
|
println("See more in:")
|
||||||
fmt.Printf("👉Website: %s\n", "https://usememos.com")
|
fmt.Printf("👉Website: %s\n", "https://usememos.com")
|
||||||
fmt.Printf("👉GitHub: %s\n", "https://github.com/usememos/memos")
|
fmt.Printf("👉GitHub: %s\n", "https://github.com/usememos/memos")
|
||||||
fmt.Println("---")
|
println("---")
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"github.com/usememos/memos/store/db"
|
"github.com/usememos/memos/store/db"
|
||||||
)
|
)
|
||||||
@ -85,7 +86,7 @@ var (
|
|||||||
|
|
||||||
fmt.Printf("Resource %5d copy %12d bytes from %s\n", res.ID, len(buf), res.InternalPath)
|
fmt.Printf("Resource %5d copy %12d bytes from %s\n", res.ID, len(buf), res.InternalPath)
|
||||||
}
|
}
|
||||||
fmt.Println("done")
|
println("done")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
27
cmd/setup.go
27
cmd/setup.go
@ -2,15 +2,16 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"github.com/usememos/memos/store/db"
|
"github.com/usememos/memos/store/db"
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -76,7 +77,7 @@ func (s setupService) Setup(ctx context.Context, hostUsername, hostPassword stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := s.createUser(ctx, hostUsername, hostPassword); err != nil {
|
if err := s.createUser(ctx, hostUsername, hostPassword); err != nil {
|
||||||
return fmt.Errorf("create user: %w", err)
|
return errors.Wrap(err, "create user")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -85,7 +86,7 @@ func (s setupService) makeSureHostUserNotExists(ctx context.Context) error {
|
|||||||
hostUserType := store.RoleHost
|
hostUserType := store.RoleHost
|
||||||
existedHostUsers, err := s.store.ListUsers(ctx, &store.FindUser{Role: &hostUserType})
|
existedHostUsers, err := s.store.ListUsers(ctx, &store.FindUser{Role: &hostUserType})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("find user list: %w", err)
|
return errors.Wrap(err, "find user list")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(existedHostUsers) != 0 {
|
if len(existedHostUsers) != 0 {
|
||||||
@ -104,37 +105,37 @@ func (s setupService) createUser(ctx context.Context, hostUsername, hostPassword
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(userCreate.Username) < 3 {
|
if len(userCreate.Username) < 3 {
|
||||||
return fmt.Errorf("username is too short, minimum length is 3")
|
return errors.New("username is too short, minimum length is 3")
|
||||||
}
|
}
|
||||||
if len(userCreate.Username) > 32 {
|
if len(userCreate.Username) > 32 {
|
||||||
return fmt.Errorf("username is too long, maximum length is 32")
|
return errors.New("username is too long, maximum length is 32")
|
||||||
}
|
}
|
||||||
if len(hostPassword) < 3 {
|
if len(hostPassword) < 3 {
|
||||||
return fmt.Errorf("password is too short, minimum length is 3")
|
return errors.New("password is too short, minimum length is 3")
|
||||||
}
|
}
|
||||||
if len(hostPassword) > 512 {
|
if len(hostPassword) > 512 {
|
||||||
return fmt.Errorf("password is too long, maximum length is 512")
|
return errors.New("password is too long, maximum length is 512")
|
||||||
}
|
}
|
||||||
if len(userCreate.Nickname) > 64 {
|
if len(userCreate.Nickname) > 64 {
|
||||||
return fmt.Errorf("nickname is too long, maximum length is 64")
|
return errors.New("nickname is too long, maximum length is 64")
|
||||||
}
|
}
|
||||||
if userCreate.Email != "" {
|
if userCreate.Email != "" {
|
||||||
if len(userCreate.Email) > 256 {
|
if len(userCreate.Email) > 256 {
|
||||||
return fmt.Errorf("email is too long, maximum length is 256")
|
return errors.New("email is too long, maximum length is 256")
|
||||||
}
|
}
|
||||||
if !util.ValidateEmail(userCreate.Email) {
|
if !util.ValidateEmail(userCreate.Email) {
|
||||||
return fmt.Errorf("invalid email format")
|
return errors.New("invalid email format")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordHash, err := bcrypt.GenerateFromPassword([]byte(hostPassword), bcrypt.DefaultCost)
|
passwordHash, err := bcrypt.GenerateFromPassword([]byte(hostPassword), bcrypt.DefaultCost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to hash password: %w", err)
|
return errors.Wrap(err, "failed to hash password")
|
||||||
}
|
}
|
||||||
|
|
||||||
userCreate.PasswordHash = string(passwordHash)
|
userCreate.PasswordHash = string(passwordHash)
|
||||||
if _, err := s.store.CreateUser(ctx, userCreate); err != nil {
|
if _, err := s.store.CreateUser(ctx, userCreate); err != nil {
|
||||||
return fmt.Errorf("failed to create user: %w", err)
|
return errors.Wrap(err, "failed to create user")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
// Package cron implements a crontab-like service to execute and schedule
|
// Package cron implements a crontab-like service to execute and schedule repeative tasks/jobs.
|
||||||
// repeative tasks/jobs.
|
package cron
|
||||||
//
|
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// c := cron.New()
|
// c := cron.New()
|
||||||
// c.MustAdd("dailyReport", "0 0 * * *", func() { ... })
|
// c.MustAdd("dailyReport", "0 0 * * *", func() { ... })
|
||||||
// c.Start()
|
// c.Start()
|
||||||
package cron
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type job struct {
|
type job struct {
|
||||||
@ -90,7 +89,7 @@ func (c *Cron) Add(jobID string, cronExpr string, run func()) error {
|
|||||||
|
|
||||||
schedule, err := NewSchedule(cronExpr)
|
schedule, err := NewSchedule(cronExpr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to add new cron job: %w", err)
|
return errors.Wrap(err, "failed to add new cron job")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.jobs[jobID] = &job{
|
c.jobs[jobID] = &job{
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package cron
|
package cron
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Moment represents a parsed single time moment.
|
// Moment represents a parsed single time moment.
|
||||||
@ -132,7 +132,7 @@ func parseCronSegment(segment string, min int, max int) (map[int]struct{}, error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if parsedStep < 1 || parsedStep > max {
|
if parsedStep < 1 || parsedStep > max {
|
||||||
return nil, fmt.Errorf("invalid segment step boundary - the step must be between 1 and the %d", max)
|
return nil, errors.Errorf("invalid segment step boundary - the step must be between 1 and the %d", max)
|
||||||
}
|
}
|
||||||
step = parsedStep
|
step = parsedStep
|
||||||
default:
|
default:
|
||||||
@ -167,7 +167,7 @@ func parseCronSegment(segment string, min int, max int) (map[int]struct{}, error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if parsedMin < min || parsedMin > max {
|
if parsedMin < min || parsedMin > max {
|
||||||
return nil, fmt.Errorf("invalid segment range minimum - must be between %d and %d", min, max)
|
return nil, errors.Errorf("invalid segment range minimum - must be between %d and %d", min, max)
|
||||||
}
|
}
|
||||||
rangeMin = parsedMin
|
rangeMin = parsedMin
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ func parseCronSegment(segment string, min int, max int) (map[int]struct{}, error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if parsedMax < parsedMin || parsedMax > max {
|
if parsedMax < parsedMin || parsedMax > max {
|
||||||
return nil, fmt.Errorf("invalid segment range maximum - must be between %d and %d", rangeMin, max)
|
return nil, errors.Errorf("invalid segment range maximum - must be between %d and %d", rangeMin, max)
|
||||||
}
|
}
|
||||||
rangeMax = parsedMax
|
rangeMax = parsedMax
|
||||||
default:
|
default:
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package getter
|
package getter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -32,7 +32,7 @@ func GetHTMLMeta(urlStr string) (*HTMLMeta, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if mediatype != "text/html" {
|
if mediatype != "text/html" {
|
||||||
return nil, fmt.Errorf("Wrong website mediatype")
|
return nil, errors.New("Wrong website mediatype")
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlMeta := extractHTMLMeta(response.Body)
|
htmlMeta := extractHTMLMeta(response.Body)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package getter
|
package getter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -29,7 +29,7 @@ func GetImage(urlStr string) (*Image, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(mediatype, "image/") {
|
if !strings.HasPrefix(mediatype, "image/") {
|
||||||
return nil, fmt.Errorf("Wrong image mediatype")
|
return nil, errors.New("Wrong image mediatype")
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyBytes, err := io.ReadAll(response.Body)
|
bodyBytes, err := io.ReadAll(response.Body)
|
||||||
|
@ -9,9 +9,10 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/idp"
|
"github.com/usememos/memos/plugin/idp"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"golang.org/x/oauth2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IdentityProvider represents an OAuth2 Identity Provider.
|
// IdentityProvider represents an OAuth2 Identity Provider.
|
||||||
@ -82,6 +83,7 @@ func (p *IdentityProvider) UserInfo(token string) (*idp.IdentityProviderUserInfo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to read response body")
|
return nil, errors.Wrap(err, "failed to read response body")
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
var claims map[string]any
|
var claims map[string]any
|
||||||
err = json.Unmarshal(body, &claims)
|
err = json.Unmarshal(body, &claims)
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/plugin/idp"
|
"github.com/usememos/memos/plugin/idp"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
@ -2,6 +2,7 @@ package s3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
@ -80,7 +81,7 @@ func (client *Client) UploadFile(ctx context.Context, filename string, fileType
|
|||||||
link = fmt.Sprintf("%s/%s%s", client.Config.URLPrefix, filename, client.Config.URLSuffix)
|
link = fmt.Sprintf("%s/%s%s", client.Config.URLPrefix, filename, client.Config.URLSuffix)
|
||||||
}
|
}
|
||||||
if link == "" {
|
if link == "" {
|
||||||
return "", fmt.Errorf("failed to get file link")
|
return "", errors.New("failed to get file link")
|
||||||
}
|
}
|
||||||
return link, nil
|
return link, nil
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,10 @@ package telegram
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EditMessage make an editMessageText api request.
|
// EditMessage make an editMessageText api request.
|
||||||
@ -23,7 +24,7 @@ func (b *Bot) EditMessage(ctx context.Context, chatID, messageID int64, text str
|
|||||||
markup.InlineKeyboard = inlineKeyboards
|
markup.InlineKeyboard = inlineKeyboards
|
||||||
data, err := json.Marshal(markup)
|
data, err := json.Marshal(markup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("fail to encode inlineKeyboard: %s", err)
|
return nil, errors.Wrap(err, "fail to encode inlineKeyboard")
|
||||||
}
|
}
|
||||||
formData.Set("reply_markup", string(data))
|
formData.Set("reply_markup", string(data))
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,9 @@ package telegram
|
|||||||
import (
|
import (
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/log"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/common/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Attachment struct {
|
type Attachment struct {
|
||||||
|
@ -7,8 +7,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/log"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/common/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
|
@ -2,10 +2,11 @@ package telegram
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Bot) downloadAttachment(ctx context.Context, message *Message) (*Attachment, error) {
|
func (b *Bot) downloadAttachment(ctx context.Context, message *Message) (*Attachment, error) {
|
||||||
@ -92,13 +93,13 @@ func (b *Bot) downloadFilepath(ctx context.Context, filePath string) ([]byte, er
|
|||||||
|
|
||||||
resp, err := http.Get(fileURL + "/" + filePath)
|
resp, err := http.Get(fileURL + "/" + filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("fail to http.Get: %s", err)
|
return nil, errors.Wrap(err, "fail to http.Get")
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("fail to io.ReadAll: %s", err)
|
return nil, errors.Wrap(err, "fail to io.ReadAll")
|
||||||
}
|
}
|
||||||
|
|
||||||
return body, nil
|
return body, nil
|
||||||
|
@ -3,10 +3,11 @@ package telegram
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Bot) postForm(ctx context.Context, apiPath string, formData url.Values, result any) error {
|
func (b *Bot) postForm(ctx context.Context, apiPath string, formData url.Values, result any) error {
|
||||||
@ -17,13 +18,13 @@ func (b *Bot) postForm(ctx context.Context, apiPath string, formData url.Values,
|
|||||||
|
|
||||||
resp, err := http.PostForm(apiURL+apiPath, formData)
|
resp, err := http.PostForm(apiURL+apiPath, formData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fail to http.PostForm: %s", err)
|
return errors.Wrap(err, "fail to http.PostForm")
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fail to ioutil.ReadAll: %s", err)
|
return errors.Wrap(err, "fail to ioutil.ReadAll")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respInfo struct {
|
var respInfo struct {
|
||||||
@ -37,11 +38,11 @@ func (b *Bot) postForm(ctx context.Context, apiPath string, formData url.Values,
|
|||||||
|
|
||||||
err = json.Unmarshal(body, &respInfo)
|
err = json.Unmarshal(body, &respInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fail to json.Unmarshal: %s", err)
|
return errors.Wrap(err, "fail to json.Unmarshal")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !respInfo.Ok {
|
if !respInfo.Ok {
|
||||||
return fmt.Errorf("api error: [%d]%s", respInfo.ErrorCode, respInfo.Description)
|
return errors.Errorf("api error: [%d]%s", respInfo.ErrorCode, respInfo.Description)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -7,7 +7,9 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/usememos/memos/server/version"
|
"github.com/usememos/memos/server/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,7 +48,7 @@ func checkDSN(dataDir string) (string, error) {
|
|||||||
dataDir = strings.TrimRight(dataDir, "\\/")
|
dataDir = strings.TrimRight(dataDir, "\\/")
|
||||||
|
|
||||||
if _, err := os.Stat(dataDir); err != nil {
|
if _, err := os.Stat(dataDir); err != nil {
|
||||||
return "", fmt.Errorf("unable to access data folder %s, err %w", dataDir, err)
|
return "", errors.Wrapf(err, "unable to access data folder %s", dataDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataDir, nil
|
return dataDir, nil
|
||||||
|
@ -14,6 +14,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
echoSwagger "github.com/swaggo/echo-swagger"
|
echoSwagger "github.com/swaggo/echo-swagger"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
apiv1 "github.com/usememos/memos/api/v1"
|
||||||
apiv2 "github.com/usememos/memos/api/v2"
|
apiv2 "github.com/usememos/memos/api/v2"
|
||||||
"github.com/usememos/memos/common/log"
|
"github.com/usememos/memos/common/log"
|
||||||
@ -21,7 +23,6 @@ import (
|
|||||||
"github.com/usememos/memos/server/profile"
|
"github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/server/service"
|
"github.com/usememos/memos/server/service"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
@ -89,7 +90,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
|
|
||||||
serverID, err := s.getSystemServerID(ctx)
|
serverID, err := s.getSystemServerID(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to retrieve system server ID: %w", err)
|
return nil, errors.Wrap(err, "failed to retrieve system server ID")
|
||||||
}
|
}
|
||||||
s.ID = serverID
|
s.ID = serverID
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
if profile.Mode == "prod" {
|
if profile.Mode == "prod" {
|
||||||
secret, err = s.getSystemSecretSessionName(ctx)
|
secret, err = s.getSystemSecretSessionName(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to retrieve system secret session name: %w", err)
|
return nil, errors.Wrap(err, "failed to retrieve system secret session name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.Secret = secret
|
s.Secret = secret
|
||||||
@ -117,7 +118,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
s.apiV2Service = apiv2.NewAPIV2Service(s.Secret, profile, store, s.Profile.Port+1)
|
s.apiV2Service = apiv2.NewAPIV2Service(s.Secret, profile, store, s.Profile.Port+1)
|
||||||
// Register gRPC gateway as api v2.
|
// Register gRPC gateway as api v2.
|
||||||
if err := s.apiV2Service.RegisterGateway(ctx, e); err != nil {
|
if err := s.apiV2Service.RegisterGateway(ctx, e); err != nil {
|
||||||
return nil, fmt.Errorf("failed to register gRPC gateway: %w", err)
|
return nil, errors.Wrap(err, "failed to register gRPC gateway")
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
|
@ -6,10 +6,11 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
apiv1 "github.com/usememos/memos/api/v1"
|
||||||
"github.com/usememos/memos/common/log"
|
"github.com/usememos/memos/common/log"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type BackupRunner struct {
|
type BackupRunner struct {
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
apiv1 "github.com/usememos/memos/api/v1"
|
||||||
"github.com/usememos/memos/plugin/telegram"
|
"github.com/usememos/memos/plugin/telegram"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
@ -34,7 +35,7 @@ const (
|
|||||||
func (t *telegramHandler) MessageHandle(ctx context.Context, bot *telegram.Bot, message telegram.Message, attachments []telegram.Attachment) error {
|
func (t *telegramHandler) MessageHandle(ctx context.Context, bot *telegram.Bot, message telegram.Message, attachments []telegram.Attachment) error {
|
||||||
reply, err := bot.SendReplyMessage(ctx, message.Chat.ID, message.MessageID, workingMessage)
|
reply, err := bot.SendReplyMessage(ctx, message.Chat.ID, message.MessageID, workingMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to SendReplyMessage: %s", err)
|
return errors.Wrap(err, "Failed to SendReplyMessage")
|
||||||
}
|
}
|
||||||
|
|
||||||
var creatorID int32
|
var creatorID int32
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"embed"
|
"embed"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
@ -12,6 +11,8 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/usememos/memos/server/profile"
|
"github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/server/version"
|
"github.com/usememos/memos/server/version"
|
||||||
)
|
)
|
||||||
@ -42,7 +43,7 @@ func NewDB(profile *profile.Profile) *DB {
|
|||||||
func (db *DB) Open() error {
|
func (db *DB) Open() error {
|
||||||
// Ensure a DSN is set before attempting to open the database.
|
// Ensure a DSN is set before attempting to open the database.
|
||||||
if db.profile.DSN == "" {
|
if db.profile.DSN == "" {
|
||||||
return fmt.Errorf("dsn required")
|
return errors.New("dsn required")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect to the database with some sane settings:
|
// Connect to the database with some sane settings:
|
||||||
@ -61,7 +62,7 @@ func (db *DB) Open() error {
|
|||||||
// - https://www.sqlite.org/pragma.html
|
// - https://www.sqlite.org/pragma.html
|
||||||
sqliteDB, err := sql.Open("sqlite", db.profile.DSN+"?_pragma=foreign_keys(0)&_pragma=busy_timeout(10000)&_pragma=journal_mode(WAL)")
|
sqliteDB, err := sql.Open("sqlite", db.profile.DSN+"?_pragma=foreign_keys(0)&_pragma=busy_timeout(10000)&_pragma=journal_mode(WAL)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open db with dsn: %s, err: %w", db.profile.DSN, err)
|
return errors.Wrapf(err, "failed to open db with dsn: %s", db.profile.DSN)
|
||||||
}
|
}
|
||||||
db.DBInstance = sqliteDB
|
db.DBInstance = sqliteDB
|
||||||
return nil
|
return nil
|
||||||
@ -75,24 +76,24 @@ func (db *DB) Migrate(ctx context.Context) error {
|
|||||||
// If db file not exists, we should create a new one with latest schema.
|
// If db file not exists, we should create a new one with latest schema.
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
if err := db.applyLatestSchema(ctx); err != nil {
|
if err := db.applyLatestSchema(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to apply latest schema, err: %w", err)
|
return errors.Wrap(err, "failed to apply latest schema")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("failed to get db file stat, err: %w", err)
|
return errors.Wrap(err, "failed to get db file stat")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If db file exists, we should check if we need to migrate the database.
|
// If db file exists, we should check if we need to migrate the database.
|
||||||
currentVersion := version.GetCurrentVersion(db.profile.Mode)
|
currentVersion := version.GetCurrentVersion(db.profile.Mode)
|
||||||
migrationHistoryList, err := db.FindMigrationHistoryList(ctx, &MigrationHistoryFind{})
|
migrationHistoryList, err := db.FindMigrationHistoryList(ctx, &MigrationHistoryFind{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to find migration history, err: %w", err)
|
return errors.Wrap(err, "failed to find migration history")
|
||||||
}
|
}
|
||||||
if len(migrationHistoryList) == 0 {
|
if len(migrationHistoryList) == 0 {
|
||||||
_, err := db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
_, err := db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
||||||
Version: currentVersion,
|
Version: currentVersion,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to upsert migration history, err: %w", err)
|
return errors.Wrap(err, "failed to upsert migration history")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -110,11 +111,11 @@ func (db *DB) Migrate(ctx context.Context) error {
|
|||||||
// backup the raw database file before migration
|
// backup the raw database file before migration
|
||||||
rawBytes, err := os.ReadFile(db.profile.DSN)
|
rawBytes, err := os.ReadFile(db.profile.DSN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read raw database file, err: %w", err)
|
return errors.Wrap(err, "failed to read raw database file")
|
||||||
}
|
}
|
||||||
backupDBFilePath := fmt.Sprintf("%s/memos_%s_%d_backup.db", db.profile.Data, db.profile.Version, time.Now().Unix())
|
backupDBFilePath := fmt.Sprintf("%s/memos_%s_%d_backup.db", db.profile.Data, db.profile.Version, time.Now().Unix())
|
||||||
if err := os.WriteFile(backupDBFilePath, rawBytes, 0644); err != nil {
|
if err := os.WriteFile(backupDBFilePath, rawBytes, 0644); err != nil {
|
||||||
return fmt.Errorf("failed to write raw database file, err: %w", err)
|
return errors.Wrap(err, "failed to write raw database file")
|
||||||
}
|
}
|
||||||
println("succeed to copy a backup database file")
|
println("succeed to copy a backup database file")
|
||||||
|
|
||||||
@ -124,7 +125,7 @@ func (db *DB) Migrate(ctx context.Context) error {
|
|||||||
if version.IsVersionGreaterThan(normalizedVersion, latestMigrationHistoryVersion) && version.IsVersionGreaterOrEqualThan(currentVersion, normalizedVersion) {
|
if version.IsVersionGreaterThan(normalizedVersion, latestMigrationHistoryVersion) && version.IsVersionGreaterOrEqualThan(currentVersion, normalizedVersion) {
|
||||||
println("applying migration for", normalizedVersion)
|
println("applying migration for", normalizedVersion)
|
||||||
if err := db.applyMigrationForMinorVersion(ctx, minorVersion); err != nil {
|
if err := db.applyMigrationForMinorVersion(ctx, minorVersion); err != nil {
|
||||||
return fmt.Errorf("failed to apply minor version migration: %w", err)
|
return errors.Wrap(err, "failed to apply minor version migration")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,12 +141,12 @@ func (db *DB) Migrate(ctx context.Context) error {
|
|||||||
// In non-prod mode, we should always migrate the database.
|
// In non-prod mode, we should always migrate the database.
|
||||||
if _, err := os.Stat(db.profile.DSN); errors.Is(err, os.ErrNotExist) {
|
if _, err := os.Stat(db.profile.DSN); errors.Is(err, os.ErrNotExist) {
|
||||||
if err := db.applyLatestSchema(ctx); err != nil {
|
if err := db.applyLatestSchema(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to apply latest schema: %w", err)
|
return errors.Wrap(err, "failed to apply latest schema")
|
||||||
}
|
}
|
||||||
// In demo mode, we should seed the database.
|
// In demo mode, we should seed the database.
|
||||||
if db.profile.Mode == "demo" {
|
if db.profile.Mode == "demo" {
|
||||||
if err := db.seed(ctx); err != nil {
|
if err := db.seed(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to seed: %w", err)
|
return errors.Wrap(err, "failed to seed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,11 +167,11 @@ func (db *DB) applyLatestSchema(ctx context.Context) error {
|
|||||||
latestSchemaPath := fmt.Sprintf("%s/%s/%s", "migration", schemaMode, latestSchemaFileName)
|
latestSchemaPath := fmt.Sprintf("%s/%s/%s", "migration", schemaMode, latestSchemaFileName)
|
||||||
buf, err := migrationFS.ReadFile(latestSchemaPath)
|
buf, err := migrationFS.ReadFile(latestSchemaPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read latest schema %q, error %w", latestSchemaPath, err)
|
return errors.Wrapf(err, "failed to read latest schema %q", latestSchemaPath)
|
||||||
}
|
}
|
||||||
stmt := string(buf)
|
stmt := string(buf)
|
||||||
if err := db.execute(ctx, stmt); err != nil {
|
if err := db.execute(ctx, stmt); err != nil {
|
||||||
return fmt.Errorf("migrate error: statement:%s err=%w", stmt, err)
|
return errors.Wrapf(err, "migrate error: %s", stmt)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -178,7 +179,7 @@ func (db *DB) applyLatestSchema(ctx context.Context) error {
|
|||||||
func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion string) error {
|
func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion string) error {
|
||||||
filenames, err := fs.Glob(migrationFS, fmt.Sprintf("%s/%s/*.sql", "migration/prod", minorVersion))
|
filenames, err := fs.Glob(migrationFS, fmt.Sprintf("%s/%s/*.sql", "migration/prod", minorVersion))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read ddl files, err: %w", err)
|
return errors.Wrap(err, "failed to read ddl files")
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
@ -188,12 +189,12 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st
|
|||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
buf, err := migrationFS.ReadFile(filename)
|
buf, err := migrationFS.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read minor version migration file, filename=%s err=%w", filename, err)
|
return errors.Wrapf(err, "failed to read minor version migration file, filename=%s", filename)
|
||||||
}
|
}
|
||||||
stmt := string(buf)
|
stmt := string(buf)
|
||||||
migrationStmt += stmt
|
migrationStmt += stmt
|
||||||
if err := db.execute(ctx, stmt); err != nil {
|
if err := db.execute(ctx, stmt); err != nil {
|
||||||
return fmt.Errorf("migrate error: statement:%s err=%w", stmt, err)
|
return errors.Wrapf(err, "migrate error: %s", stmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +203,7 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st
|
|||||||
if _, err = db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
if _, err = db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
||||||
Version: version,
|
Version: version,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("failed to upsert migration history with version: %s, err: %w", version, err)
|
return errors.Wrapf(err, "failed to upsert migration history with version: %s", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -211,7 +212,7 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st
|
|||||||
func (db *DB) seed(ctx context.Context) error {
|
func (db *DB) seed(ctx context.Context) error {
|
||||||
filenames, err := fs.Glob(seedFS, fmt.Sprintf("%s/*.sql", "seed"))
|
filenames, err := fs.Glob(seedFS, fmt.Sprintf("%s/*.sql", "seed"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read seed files, err: %w", err)
|
return errors.Wrap(err, "failed to read seed files")
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
@ -220,11 +221,11 @@ func (db *DB) seed(ctx context.Context) error {
|
|||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
buf, err := seedFS.ReadFile(filename)
|
buf, err := seedFS.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read seed file, filename=%s err=%w", filename, err)
|
return errors.Wrapf(err, "failed to read seed file, filename=%s", filename)
|
||||||
}
|
}
|
||||||
stmt := string(buf)
|
stmt := string(buf)
|
||||||
if err := db.execute(ctx, stmt); err != nil {
|
if err := db.execute(ctx, stmt); err != nil {
|
||||||
return fmt.Errorf("seed error: statement:%s err=%w", stmt, err)
|
return errors.Wrapf(err, "seed error: %s", stmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -239,7 +240,7 @@ func (db *DB) execute(ctx context.Context, stmt string) error {
|
|||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
if _, err := tx.ExecContext(ctx, stmt); err != nil {
|
if _, err := tx.ExecContext(ctx, stmt); err != nil {
|
||||||
return fmt.Errorf("failed to execute statement, err: %w", err)
|
return errors.Wrap(err, "failed to execute statement")
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx.Commit()
|
return tx.Commit()
|
||||||
|
10
store/idp.go
10
store/idp.go
@ -5,6 +5,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IdentityProviderType string
|
type IdentityProviderType string
|
||||||
@ -70,7 +72,7 @@ func (s *Store) CreateIdentityProvider(ctx context.Context, create *IdentityProv
|
|||||||
}
|
}
|
||||||
configBytes = bytes
|
configBytes = bytes
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unsupported idp type %s", string(create.Type))
|
return nil, errors.Errorf("unsupported idp type %s", string(create.Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt := `
|
stmt := `
|
||||||
@ -146,7 +148,7 @@ func (s *Store) ListIdentityProviders(ctx context.Context, find *FindIdentityPro
|
|||||||
OAuth2Config: oauth2Config,
|
OAuth2Config: oauth2Config,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
||||||
}
|
}
|
||||||
identityProviders = append(identityProviders, &identityProvider)
|
identityProviders = append(identityProviders, &identityProvider)
|
||||||
}
|
}
|
||||||
@ -198,7 +200,7 @@ func (s *Store) UpdateIdentityProvider(ctx context.Context, update *UpdateIdenti
|
|||||||
}
|
}
|
||||||
configBytes = bytes
|
configBytes = bytes
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unsupported idp type %s", string(update.Type))
|
return nil, errors.Errorf("unsupported idp type %s", string(update.Type))
|
||||||
}
|
}
|
||||||
set, args = append(set, "config = ?"), append(args, string(configBytes))
|
set, args = append(set, "config = ?"), append(args, string(configBytes))
|
||||||
}
|
}
|
||||||
@ -231,7 +233,7 @@ func (s *Store) UpdateIdentityProvider(ctx context.Context, update *UpdateIdenti
|
|||||||
OAuth2Config: oauth2Config,
|
OAuth2Config: oauth2Config,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.idpCache.Store(identityProvider.ID, identityProvider)
|
s.idpCache.Store(identityProvider.ID, identityProvider)
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -244,7 +246,7 @@ func (s *Store) ListMemos(ctx context.Context, find *FindMemo) ([]*Memo, error)
|
|||||||
for _, relatedMemoType := range relatedMemoTypeList {
|
for _, relatedMemoType := range relatedMemoTypeList {
|
||||||
relatedMemoTypeList := strings.Split(relatedMemoType, ":")
|
relatedMemoTypeList := strings.Split(relatedMemoType, ":")
|
||||||
if len(relatedMemoTypeList) != 2 {
|
if len(relatedMemoTypeList) != 2 {
|
||||||
return nil, fmt.Errorf("invalid relation format")
|
return nil, errors.Errorf("invalid relation format")
|
||||||
}
|
}
|
||||||
relatedMemoID, err := util.ConvertStringToInt32(relatedMemoTypeList[0])
|
relatedMemoID, err := util.ConvertStringToInt32(relatedMemoTypeList[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -3,11 +3,13 @@ package store
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/usememos/memos/server/profile"
|
|
||||||
"modernc.org/sqlite"
|
"modernc.org/sqlite"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/server/profile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Store provides database access to all raw objects.
|
// Store provides database access to all raw objects.
|
||||||
@ -35,7 +37,7 @@ func (s *Store) GetDB() *sql.DB {
|
|||||||
func (s *Store) BackupTo(ctx context.Context, filename string) error {
|
func (s *Store) BackupTo(ctx context.Context, filename string) error {
|
||||||
conn, err := s.db.Conn(ctx)
|
conn, err := s.db.Conn(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fail to get conn %s", err)
|
return errors.Errorf("fail to get conn %s", err)
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
@ -45,25 +47,25 @@ func (s *Store) BackupTo(ctx context.Context, filename string) error {
|
|||||||
}
|
}
|
||||||
backupConn, ok := driverConn.(backuper)
|
backupConn, ok := driverConn.(backuper)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("db connection is not a sqlite backuper")
|
return errors.Errorf("db connection is not a sqlite backuper")
|
||||||
}
|
}
|
||||||
|
|
||||||
bck, err := backupConn.NewBackup(filename)
|
bck, err := backupConn.NewBackup(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fail to create sqlite backup %s", err)
|
return errors.Errorf("fail to create sqlite backup %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for more := true; more; {
|
for more := true; more; {
|
||||||
more, err = bck.Step(-1)
|
more, err = bck.Step(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fail to execute sqlite backup %s", err)
|
return errors.Errorf("fail to execute sqlite backup %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bck.Finish()
|
return bck.Finish()
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fail to backup %s", err)
|
return errors.Errorf("fail to backup %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -6,8 +6,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
storepb "github.com/usememos/memos/proto/gen/store"
|
|
||||||
"google.golang.org/protobuf/encoding/protojson"
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
|
||||||
|
storepb "github.com/usememos/memos/proto/gen/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserSetting struct {
|
type UserSetting struct {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
apiv1 "github.com/usememos/memos/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
apiv1 "github.com/usememos/memos/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
apiv1 "github.com/usememos/memos/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,15 +11,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
// sqlite driver.
|
||||||
|
_ "modernc.org/sqlite"
|
||||||
|
|
||||||
"github.com/usememos/memos/api/auth"
|
"github.com/usememos/memos/api/auth"
|
||||||
"github.com/usememos/memos/server"
|
"github.com/usememos/memos/server"
|
||||||
"github.com/usememos/memos/server/profile"
|
"github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
"github.com/usememos/memos/store/db"
|
"github.com/usememos/memos/store/db"
|
||||||
"github.com/usememos/memos/test"
|
"github.com/usememos/memos/test"
|
||||||
|
|
||||||
// sqlite driver.
|
|
||||||
_ "modernc.org/sqlite"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestingServer struct {
|
type TestingServer struct {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
apiv1 "github.com/usememos/memos/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
apiv1 "github.com/usememos/memos/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,8 +5,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUserStore(t *testing.T) {
|
func TestUserStore(t *testing.T) {
|
||||||
|
Reference in New Issue
Block a user