feat: personal memos page (#105)

* feat: no need to log in to view memos

* chore: add a normal user to seed

* feat: page for other members

* fix: replace window.location

* fix: can not get username on home

* fix: check userID

* fix: can visit other user's page after login

* fix: do not redirect on wrong path

* fix: path error when clicked heatmap

* refactor: revise for review

* chore: remove unused import

* refactor: revise for review

* feat: update each user's route to /u/:userId.

* chore: eslint for import sort

* refactor: revise for review
This commit is contained in:
Hyoban
2022-07-07 20:22:36 +08:00
committed by GitHub
parent e202d7b8d6
commit 6b5d5e757e
21 changed files with 286 additions and 99 deletions

View File

@ -59,6 +59,10 @@ func BasicAuthMiddleware(s *Server, next echo.HandlerFunc) echo.HandlerFunc {
return next(c)
}
if common.HasPrefixes(c.Path(), "/api/memo", "/api/tag", "/api/shortcut", "/api/user/:id/name") && c.Request().Method == http.MethodGet {
return next(c)
}
// If there is openId in query string and related user is found, then skip auth.
openID := c.QueryParam("openId")
if openID != "" {

View File

@ -60,7 +60,29 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
})
g.GET("/memo", func(c echo.Context) error {
userID := c.Get(getUserIDContextKey()).(int)
userID, ok := c.Get(getUserIDContextKey()).(int)
if !ok {
if c.QueryParam("userID") != "" {
var err error
userID, err = strconv.Atoi(c.QueryParam("userID"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.QueryParam("userID")))
}
} else {
ownerUserType := api.Owner
ownerUser, err := s.Store.FindUser(&api.UserFind{
Role: &ownerUserType,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find owner user").SetInternal(err)
}
if ownerUser == nil {
return echo.NewHTTPError(http.StatusNotFound, "Owner user do not exist")
}
userID = ownerUser.ID
}
}
memoFind := &api.MemoFind{
CreatorID: &userID,
}

View File

@ -59,7 +59,29 @@ func (s *Server) registerShortcutRoutes(g *echo.Group) {
})
g.GET("/shortcut", func(c echo.Context) error {
userID := c.Get(getUserIDContextKey()).(int)
userID, ok := c.Get(getUserIDContextKey()).(int)
if !ok {
if c.QueryParam("userID") != "" {
var err error
userID, err = strconv.Atoi(c.QueryParam("userID"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.QueryParam("userID")))
}
} else {
ownerUserType := api.Owner
ownerUser, err := s.Store.FindUser(&api.UserFind{
Role: &ownerUserType,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find owner user").SetInternal(err)
}
if ownerUser == nil {
return echo.NewHTTPError(http.StatusNotFound, "Owner user do not exist")
}
userID = ownerUser.ID
}
}
shortcutFind := &api.ShortcutFind{
CreatorID: &userID,
}

View File

@ -2,9 +2,11 @@ package server
import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"sort"
"strconv"
"github.com/usememos/memos/api"
@ -13,7 +15,29 @@ import (
func (s *Server) registerTagRoutes(g *echo.Group) {
g.GET("/tag", func(c echo.Context) error {
userID := c.Get(getUserIDContextKey()).(int)
userID, ok := c.Get(getUserIDContextKey()).(int)
if !ok {
if c.QueryParam("userID") != "" {
var err error
userID, err = strconv.Atoi(c.QueryParam("userID"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.QueryParam("userID")))
}
} else {
ownerUserType := api.Owner
ownerUser, err := s.Store.FindUser(&api.UserFind{
Role: &ownerUserType,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find owner user").SetInternal(err)
}
if ownerUser == nil {
return echo.NewHTTPError(http.StatusNotFound, "Owner user do not exist")
}
userID = ownerUser.ID
}
}
contentSearch := "#"
normalRowStatus := api.Normal
memoFind := api.MemoFind{

View File

@ -51,6 +51,29 @@ func (s *Server) registerUserRoutes(g *echo.Group) {
return nil
})
g.GET("/user/:id/name", func(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted user id").SetInternal(err)
}
user, err := s.Store.FindUser(&api.UserFind{
ID: &id,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to fetch user").SetInternal(err)
}
if user == nil {
return echo.NewHTTPError(http.StatusNotFound, "User not found")
}
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8)
if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(user.Name)); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to encode user response").SetInternal(err)
}
return nil
})
// GET /api/user/me is used to check if the user is logged in.
g.GET("/user/me", func(c echo.Context) error {
userSessionID := c.Get(getUserIDContextKey())