diff --git a/server/common.go b/server/common.go index 9c3b129734a72..054fe6b707b88 100644 --- a/server/common.go +++ b/server/common.go @@ -1,6 +1,8 @@ package server import ( + "net/http" + "github.com/labstack/echo/v4" "github.com/usememos/memos/api" "github.com/usememos/memos/common" @@ -16,6 +18,10 @@ func composeResponse(data interface{}) response { } } +func DefaultGetRequestSkipper(c echo.Context) bool { + return c.Request().Method == http.MethodGet +} + func (server *Server) DefaultAuthSkipper(c echo.Context) bool { ctx := c.Request().Context() path := c.Path() diff --git a/server/resource.go b/server/resource.go index 07ca84a4cbbc6..f46d1ece753ac 100644 --- a/server/resource.go +++ b/server/resource.go @@ -7,6 +7,7 @@ import ( "net/http" "net/url" "strconv" + "strings" "time" "github.com/pkg/errors" @@ -266,7 +267,11 @@ func (s *Server) registerResourcePublicRoutes(g *echo.Group) { return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to fetch resource ID: %v", resourceID)).SetInternal(err) } - c.Response().Writer.Header().Set("Content-Type", resource.Type) + if strings.HasPrefix(resource.Type, "text") || strings.HasPrefix(resource.Type, "application") { + c.Response().Writer.Header().Set("Content-Type", echo.MIMETextPlain) + } else { + c.Response().Writer.Header().Set("Content-Type", resource.Type) + } c.Response().Writer.WriteHeader(http.StatusOK) c.Response().Writer.Header().Set(echo.HeaderCacheControl, "max-age=31536000, immutable") c.Response().Writer.Header().Set(echo.HeaderContentSecurityPolicy, "default-src 'self'") diff --git a/server/server.go b/server/server.go index af299820931b6..9df7ce5a3dd45 100644 --- a/server/server.go +++ b/server/server.go @@ -64,7 +64,13 @@ func NewServer(ctx context.Context, profile *profile.Profile) (*Server, error) { e.Use(middleware.CORS()) - e.Use(middleware.Secure()) + e.Use(middleware.SecureWithConfig(middleware.SecureConfig{ + Skipper: DefaultGetRequestSkipper, + XSSProtection: "1; mode=block", + ContentTypeNosniff: "nosniff", + XFrameOptions: "SAMEORIGIN", + HSTSPreloadEnabled: false, + })) e.Use(middleware.TimeoutWithConfig(middleware.TimeoutConfig{ Skipper: middleware.DefaultSkipper, diff --git a/server/version/version.go b/server/version/version.go index 6f83fda9ebfd5..49021b4aa4f17 100644 --- a/server/version/version.go +++ b/server/version/version.go @@ -7,10 +7,10 @@ import ( // Version is the service current released version. // Semantic versioning: https://semver.org/ -var Version = "0.9.1" +var Version = "0.10.0" // DevVersion is the service current development version. -var DevVersion = "0.9.1" +var DevVersion = "0.10.0" func GetCurrentVersion(mode string) string { if mode == "dev" { @@ -29,7 +29,6 @@ func GetMinorVersion(version string) string { func GetSchemaVersion(version string) string { minorVersion := GetMinorVersion(version) - return minorVersion + ".0" } diff --git a/server/version/version_test.go b/server/version/version_test.go new file mode 100644 index 0000000000000..21be7c95f3215 --- /dev/null +++ b/server/version/version_test.go @@ -0,0 +1,33 @@ +package version + +import "testing" + +func TestIsVersionGreaterOrEqualThan(t *testing.T) { + tests := []struct { + version string + target string + want bool + }{ + { + version: "0.9.1", + target: "0.9.1", + want: true, + }, + { + version: "0.10.0", + target: "0.9.1", + want: true, + }, + { + version: "0.9.0", + target: "0.9.1", + want: false, + }, + } + for _, test := range tests { + result := IsVersionGreaterOrEqualThan(test.version, test.target) + if result != test.want { + t.Errorf("got result %v, want %v.", result, test.want) + } + } +} diff --git a/store/db/migration/prod/0.10/00__activity.sql b/store/db/migration/prod/0.10/00__activity.sql new file mode 100644 index 0000000000000..0d4b05e7a4b19 --- /dev/null +++ b/store/db/migration/prod/0.10/00__activity.sql @@ -0,0 +1,9 @@ +-- activity +CREATE TABLE activity ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + creator_id INTEGER NOT NULL, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + type TEXT NOT NULL DEFAULT '', + level TEXT NOT NULL CHECK (level IN ('INFO', 'WARN', 'ERROR')) DEFAULT 'INFO', + payload TEXT NOT NULL DEFAULT '{}' +); diff --git a/store/db/migration/prod/LATEST__SCHEMA.sql b/store/db/migration/prod/LATEST__SCHEMA.sql index 3b7b4adb8e371..7e94c60165fcc 100644 --- a/store/db/migration/prod/LATEST__SCHEMA.sql +++ b/store/db/migration/prod/LATEST__SCHEMA.sql @@ -93,3 +93,13 @@ CREATE TABLE tag ( creator_id INTEGER NOT NULL, UNIQUE(name, creator_id) ); + +-- activity +CREATE TABLE activity ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + creator_id INTEGER NOT NULL, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + type TEXT NOT NULL DEFAULT '', + level TEXT NOT NULL CHECK (level IN ('INFO', 'WARN', 'ERROR')) DEFAULT 'INFO', + payload TEXT NOT NULL DEFAULT '{}' +); diff --git a/web/src/components/EmbedMemoDialog.tsx b/web/src/components/EmbedMemoDialog.tsx index f3d3c4f5fe42a..aed984de0fe74 100644 --- a/web/src/components/EmbedMemoDialog.tsx +++ b/web/src/components/EmbedMemoDialog.tsx @@ -34,7 +34,7 @@ const EmbedMemoDialog: React.FC = (props: Props) => { {memoEmbeddedCode()}

- * Only the public memo supports. + * Only the public memo supports. Copy