diff --git a/api/memo.go b/api/memo.go index 44df4e4d..a42ffceb 100644 --- a/api/memo.go +++ b/api/memo.go @@ -37,6 +37,9 @@ type Memo struct { Content string `json:"content"` Visibility Visibility `json:"visibility"` Pinned bool `json:"pinned"` + + // Related fields + Creator *User `json:"creator"` } type MemoCreate struct { diff --git a/bin/server/cmd/root.go b/bin/server/cmd/root.go deleted file mode 100644 index 0e1652cd..00000000 --- a/bin/server/cmd/root.go +++ /dev/null @@ -1,63 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - - "github.com/usememos/memos/server" - "github.com/usememos/memos/server/profile" - "github.com/usememos/memos/store" - DB "github.com/usememos/memos/store/db" -) - -const ( - greetingBanner = ` -███╗ ███╗███████╗███╗ ███╗ ██████╗ ███████╗ -████╗ ████║██╔════╝████╗ ████║██╔═══██╗██╔════╝ -██╔████╔██║█████╗ ██╔████╔██║██║ ██║███████╗ -██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║██║ ██║╚════██║ -██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║╚██████╔╝███████║ -╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ -` -) - -func Run(profile *profile.Profile) error { - ctx := context.Background() - - db := DB.NewDB(profile) - if err := db.Open(ctx); err != nil { - return fmt.Errorf("cannot open db: %w", err) - } - - s := server.NewServer(profile) - - storeInstance := store.New(db.Db, profile) - s.Store = storeInstance - - println(greetingBanner) - fmt.Printf("Version %s has started at :%d\n", profile.Version, profile.Port) - - return s.Run() -} - -func Execute() error { - profile, err := profile.GetProfile() - if err != nil { - return err - } - - println("---") - println("profile") - println("mode:", profile.Mode) - println("port:", profile.Port) - println("dsn:", profile.DSN) - println("version:", profile.Version) - println("---") - - if err := Run(profile); err != nil { - fmt.Printf("error: %+v\n", err) - return err - } - - return nil -} diff --git a/bin/server/main.go b/bin/server/main.go index 670d2009..9135d2ba 100644 --- a/bin/server/main.go +++ b/bin/server/main.go @@ -5,11 +5,70 @@ import ( _ "github.com/mattn/go-sqlite3" - "github.com/usememos/memos/bin/server/cmd" + "context" + "fmt" + + "github.com/usememos/memos/server" + "github.com/usememos/memos/server/profile" + "github.com/usememos/memos/store" + + DB "github.com/usememos/memos/store/db" ) +const ( + greetingBanner = ` +███╗ ███╗███████╗███╗ ███╗ ██████╗ ███████╗ +████╗ ████║██╔════╝████╗ ████║██╔═══██╗██╔════╝ +██╔████╔██║█████╗ ██╔████╔██║██║ ██║███████╗ +██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║██║ ██║╚════██║ +██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║╚██████╔╝███████║ +╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ +` +) + +func run(profile *profile.Profile) error { + ctx := context.Background() + + db := DB.NewDB(profile) + if err := db.Open(ctx); err != nil { + return fmt.Errorf("cannot open db: %w", err) + } + + s := server.NewServer(profile) + + storeInstance := store.New(db.Db, profile) + s.Store = storeInstance + + println(greetingBanner) + fmt.Printf("Version %s has started at :%d\n", profile.Version, profile.Port) + + return s.Run() +} + +func execute() error { + profile, err := profile.GetProfile() + if err != nil { + return err + } + + println("---") + println("profile") + println("mode:", profile.Mode) + println("port:", profile.Port) + println("dsn:", profile.DSN) + println("version:", profile.Version) + println("---") + + if err := run(profile); err != nil { + fmt.Printf("error: %+v\n", err) + return err + } + + return nil +} + func main() { - if err := cmd.Execute(); err != nil { + if err := execute(); err != nil { os.Exit(1) } } diff --git a/server/acl.go b/server/acl.go index db52c88a..ca5a4571 100644 --- a/server/acl.go +++ b/server/acl.go @@ -102,6 +102,10 @@ func aclMiddleware(s *Server, next echo.HandlerFunc) echo.HandlerFunc { } } + if common.HasPrefixes(path, "/api/memo/all") && c.Request().Method == http.MethodGet { + return next(c) + } + if common.HasPrefixes(path, "/api/memo", "/api/tag", "/api/shortcut") && c.Request().Method == http.MethodGet { if _, err := strconv.Atoi(c.QueryParam("creatorId")); err == nil { return next(c) diff --git a/server/memo.go b/server/memo.go index b41407d0..e62b5459 100644 --- a/server/memo.go +++ b/server/memo.go @@ -151,6 +151,58 @@ func (s *Server) registerMemoRoutes(g *echo.Group) { return nil }) + g.GET("/memo/all", func(c echo.Context) error { + ctx := c.Request().Context() + memoFind := &api.MemoFind{} + + _, ok := c.Get(getUserIDContextKey()).(int) + if !ok { + memoFind.VisibilityList = []api.Visibility{api.Public} + } else { + memoFind.VisibilityList = []api.Visibility{api.Public, api.Protected} + } + + rowStatus := api.RowStatus(c.QueryParam("rowStatus")) + if rowStatus != "" { + memoFind.RowStatus = &rowStatus + } + pinnedStr := c.QueryParam("pinned") + if pinnedStr != "" { + pinned := pinnedStr == "true" + memoFind.Pinned = &pinned + } + tag := c.QueryParam("tag") + if tag != "" { + contentSearch := "#" + tag + " " + memoFind.ContentSearch = &contentSearch + } + visibilitListStr := c.QueryParam("visibility") + if visibilitListStr != "" { + visibilityList := []api.Visibility{} + for _, visibility := range strings.Split(visibilitListStr, ",") { + visibilityList = append(visibilityList, api.Visibility(visibility)) + } + memoFind.VisibilityList = visibilityList + } + if limit, err := strconv.Atoi(c.QueryParam("limit")); err == nil { + memoFind.Limit = limit + } + if offset, err := strconv.Atoi(c.QueryParam("offset")); err == nil { + memoFind.Offset = offset + } + + list, err := s.Store.FindMemoList(ctx, memoFind) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to fetch all memo list").SetInternal(err) + } + + c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) + if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(list)); err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to encode all memo list response").SetInternal(err) + } + return nil + }) + g.POST("/memo/:memoId/organizer", func(c echo.Context) error { ctx := c.Request().Context() memoID, err := strconv.Atoi(c.Param("memoId")) diff --git a/store/memo.go b/store/memo.go index b8cfcc49..031faa44 100644 --- a/store/memo.go +++ b/store/memo.go @@ -57,6 +57,11 @@ func (s *Store) composeMemo(ctx context.Context, raw *memoRaw) (*api.Memo, error memo.Pinned = memoOrganizer.Pinned } + err = s.ComposeMemoCreator(ctx, memo) + if err != nil { + return nil, err + } + return memo, nil } diff --git a/store/user.go b/store/user.go index e0ed79a8..dc3a34c3 100644 --- a/store/user.go +++ b/store/user.go @@ -44,6 +44,20 @@ func (raw *userRaw) toUser() *api.User { } } +func (s *Store) ComposeMemoCreator(ctx context.Context, memo *api.Memo) error { + user, err := s.FindUser(ctx, &api.UserFind{ + ID: &memo.CreatorID, + }) + if err != nil { + return err + } + user.OpenID = "" + user.UserSettingList = nil + memo.Creator = user + + return nil +} + func (s *Store) CreateUser(ctx context.Context, create *api.UserCreate) (*api.User, error) { tx, err := s.db.BeginTx(ctx, nil) if err != nil { @@ -138,9 +152,9 @@ func (s *Store) FindUser(ctx context.Context, find *api.UserFind) (*api.User, er } if len(list) == 0 { - return nil, nil + return nil, &common.Error{Code: common.NotFound, Err: fmt.Errorf("not found user with filter %+v", find)} } else if len(list) > 1 { - return nil, &common.Error{Code: common.Conflict, Err: fmt.Errorf("found %d users with filter %+v, expect 1. ", len(list), find)} + return nil, &common.Error{Code: common.Conflict, Err: fmt.Errorf("found %d users with filter %+v, expect 1", len(list), find)} } user := list[0].toUser()