From 8bf7cdfd31037734ea91198b8d11fa3775a5faac Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 27 Jul 2024 19:24:37 +0800 Subject: [PATCH] feat: add password auth flag --- bin/memos/main.go | 64 +++++------ docs/apidocs.swagger.yaml | 3 + go.mod | 21 ++-- go.sum | 6 +- proto/api/v1/workspace_service.proto | 2 + proto/gen/api/v1/workspace_service.pb.go | 72 +++++++------ server/profile/profile.go | 64 +++++------ server/router/api/v1/auth_service.go | 2 +- server/router/api/v1/workspace_service.go | 10 +- server/server.go | 6 +- .../s3_object_presigner.go | 2 +- store/db/mysql/mysql.go | 2 +- web/src/pages/SignIn.tsx | 98 +++++++++-------- web/src/pages/SignUp.tsx | 100 +++++++++--------- 14 files changed, 236 insertions(+), 216 deletions(-) diff --git a/bin/memos/main.go b/bin/memos/main.go index 56cd4dd8..3e5d68a2 100644 --- a/bin/memos/main.go +++ b/bin/memos/main.go @@ -14,6 +14,7 @@ import ( "github.com/usememos/memos/server" "github.com/usememos/memos/server/profile" + "github.com/usememos/memos/server/version" "github.com/usememos/memos/store" "github.com/usememos/memos/store/db" ) @@ -30,13 +31,6 @@ const ( ) var ( - mode string - addr string - port int - data string - driver string - dsn string - public bool instanceProfile *profile.Profile rootCmd = &cobra.Command{ @@ -47,26 +41,26 @@ var ( dbDriver, err := db.NewDBDriver(instanceProfile) if err != nil { cancel() - slog.Error("failed to create db driver", err) + slog.Error("failed to create db driver", "error", err) return } if err := dbDriver.Migrate(ctx); err != nil { cancel() - slog.Error("failed to migrate database", err) + slog.Error("failed to migrate database", "error", err) return } storeInstance := store.New(dbDriver, instanceProfile) if err := storeInstance.MigrateManually(ctx); err != nil { cancel() - slog.Error("failed to migrate manually", err) + slog.Error("failed to migrate manually", "error", err) return } s, err := server.NewServer(ctx, instanceProfile, storeInstance) if err != nil { cancel() - slog.Error("failed to create server", err) + slog.Error("failed to create server", "error", err) return } @@ -78,7 +72,7 @@ var ( if err := s.Start(ctx); err != nil { if err != http.ErrServerClosed { - slog.Error("failed to start server", err) + slog.Error("failed to start server", "error", err) cancel() } } @@ -102,15 +96,14 @@ func Execute() error { } func init() { - cobra.OnInitialize(initConfig) - - rootCmd.PersistentFlags().StringVarP(&mode, "mode", "m", "demo", `mode of server, can be "prod" or "dev" or "demo"`) - rootCmd.PersistentFlags().StringVarP(&addr, "addr", "a", "", "address of server") - rootCmd.PersistentFlags().IntVarP(&port, "port", "p", 8081, "port of server") - rootCmd.PersistentFlags().StringVarP(&data, "data", "d", "", "data directory") - rootCmd.PersistentFlags().StringVarP(&driver, "driver", "", "", "database driver") - rootCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "database source name(aka. DSN)") - rootCmd.PersistentFlags().BoolVarP(&public, "public", "", false, "") + rootCmd.PersistentFlags().String("mode", "demo", `mode of server, can be "prod" or "dev" or "demo"`) + rootCmd.PersistentFlags().String("addr", "", "address of server") + rootCmd.PersistentFlags().Int("port", 8081, "port of server") + rootCmd.PersistentFlags().String("data", "", "data directory") + rootCmd.PersistentFlags().String("driver", "sqlite", "database driver") + rootCmd.PersistentFlags().String("dsn", "", "database source name(aka. DSN)") + rootCmd.PersistentFlags().Bool("public", false, "") + rootCmd.PersistentFlags().Bool("password-auth", true, "") err := viper.BindPFlag("mode", rootCmd.PersistentFlags().Lookup("mode")) if err != nil { @@ -140,22 +133,32 @@ func init() { if err != nil { panic(err) } + err = viper.BindPFlag("password-auth", rootCmd.PersistentFlags().Lookup("password-auth")) + if err != nil { + panic(err) + } viper.SetDefault("mode", "demo") viper.SetDefault("driver", "sqlite") viper.SetDefault("addr", "") viper.SetDefault("port", 8081) viper.SetDefault("public", false) + viper.SetDefault("password-auth", true) viper.SetEnvPrefix("memos") -} -func initConfig() { - viper.AutomaticEnv() - var err error - instanceProfile, err = profile.GetProfile() - if err != nil { - slog.Error("failed to get profile", err) - return + instanceProfile = &profile.Profile{ + Mode: viper.GetString("mode"), + Addr: viper.GetString("addr"), + Port: viper.GetInt("port"), + Data: viper.GetString("data"), + Driver: viper.GetString("driver"), + DSN: viper.GetString("dsn"), + Public: viper.GetBool("public"), + PasswordAuth: viper.GetBool("password-auth"), + Version: version.GetCurrentVersion(viper.GetString("mode")), + } + if err := instanceProfile.Validate(); err != nil { + panic(err) } fmt.Printf(`--- @@ -167,9 +170,10 @@ addr: %s port: %d mode: %s public: %t +password-auth: %t driver: %s --- -`, instanceProfile.Version, instanceProfile.Data, instanceProfile.DSN, instanceProfile.Addr, instanceProfile.Port, instanceProfile.Mode, instanceProfile.Public, instanceProfile.Driver) +`, instanceProfile.Version, instanceProfile.Data, instanceProfile.DSN, instanceProfile.Addr, instanceProfile.Port, instanceProfile.Mode, instanceProfile.Public, instanceProfile.PasswordAuth, instanceProfile.Driver) } func printGreetings() { diff --git a/docs/apidocs.swagger.yaml b/docs/apidocs.swagger.yaml index 5f6ccc9c..7d62d84b 100644 --- a/docs/apidocs.swagger.yaml +++ b/docs/apidocs.swagger.yaml @@ -3149,3 +3149,6 @@ definitions: public: type: boolean description: public is a flag that the instance is open for other users. + passwordAuth: + type: boolean + description: password_auth is a flag whether the instance allows password authentication. diff --git a/go.mod b/go.mod index 7476a0d4..2ca73bce 100644 --- a/go.mod +++ b/go.mod @@ -41,17 +41,28 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/rs/cors v1.10.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect modernc.org/libc v1.52.1 // indirect modernc.org/mathutil v1.6.0 // indirect @@ -77,30 +88,20 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect github.com/aws/smithy-go v1.20.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v5 v5.2.1 - github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/labstack/gommon v0.4.2 // indirect - github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/soheilhy/cmux v0.1.5 - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/subosito/gotenv v1.6.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - go.uber.org/multierr v1.11.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/protobuf v1.34.2 - gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 435144da..23a76315 100644 --- a/go.sum +++ b/go.sum @@ -455,12 +455,14 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= diff --git a/proto/api/v1/workspace_service.proto b/proto/api/v1/workspace_service.proto index 12568d18..a6dc1c60 100644 --- a/proto/api/v1/workspace_service.proto +++ b/proto/api/v1/workspace_service.proto @@ -23,6 +23,8 @@ message WorkspaceProfile { string mode = 3; // public is a flag that the instance is open for other users. bool public = 4; + // password_auth is a flag whether the instance allows password authentication. + bool password_auth = 5; } message GetWorkspaceProfileRequest {} diff --git a/proto/gen/api/v1/workspace_service.pb.go b/proto/gen/api/v1/workspace_service.pb.go index 312ef5d8..a4fea41e 100644 --- a/proto/gen/api/v1/workspace_service.pb.go +++ b/proto/gen/api/v1/workspace_service.pb.go @@ -35,6 +35,8 @@ type WorkspaceProfile struct { Mode string `protobuf:"bytes,3,opt,name=mode,proto3" json:"mode,omitempty"` // public is a flag that the instance is open for other users. Public bool `protobuf:"varint,4,opt,name=public,proto3" json:"public,omitempty"` + // password_auth is a flag whether the instance allows password authentication. + PasswordAuth bool `protobuf:"varint,5,opt,name=password_auth,json=passwordAuth,proto3" json:"password_auth,omitempty"` } func (x *WorkspaceProfile) Reset() { @@ -97,6 +99,13 @@ func (x *WorkspaceProfile) GetPublic() bool { return false } +func (x *WorkspaceProfile) GetPasswordAuth() bool { + if x != nil { + return x.PasswordAuth + } + return false +} + type GetWorkspaceProfileRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -142,37 +151,40 @@ var file_api_v1_workspace_service_proto_rawDesc = []byte{ 0x63, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6e, 0x0a, 0x10, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x93, 0x01, 0x0a, + 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x23, 0x0a, + 0x0d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x75, + 0x74, 0x68, 0x22, 0x1c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x32, 0x97, 0x01, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x28, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x22, 0x1c, 0x0a, 0x1a, - 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0x97, 0x01, 0x0a, 0x10, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x82, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x70, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x42, 0xad, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x42, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, - 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x61, - 0x70, 0x69, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, - 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, - 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, - 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, + 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0xad, 0x01, 0x0a, 0x10, 0x63, + 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x42, + 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, + 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x31, 0xca, + 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x31, 0xe2, 0x02, + 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, + 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/server/profile/profile.go b/server/profile/profile.go index 55c14ea8..f5ab8fd7 100644 --- a/server/profile/profile.go +++ b/server/profile/profile.go @@ -8,30 +8,29 @@ import ( "strings" "github.com/pkg/errors" - "github.com/spf13/viper" - - "github.com/usememos/memos/server/version" ) // Profile is the configuration to start main server. type Profile struct { // Mode can be "prod" or "dev" or "demo" - Mode string `json:"mode"` + Mode string // Addr is the binding address for server - Addr string `json:"-"` + Addr string // Port is the binding port for server - Port int `json:"-"` + Port int // Data is the data directory - Data string `json:"-"` + Data string // DSN points to where memos stores its own data - DSN string `json:"-"` + DSN string // Driver is the database driver // sqlite, mysql - Driver string `json:"-"` + Driver string // Version is the current version of server - Version string `json:"version"` + Version string // Pubic is the flag whether the instance is public for others. - Public bool `json:"public"` + Public bool + // PasswordAuth is the flag whether the instance uses password authentication. + PasswordAuth bool } func (p *Profile) IsDev() bool { @@ -57,45 +56,36 @@ func checkDataDir(dataDir string) (string, error) { return dataDir, nil } -// GetProfile will return a profile for dev or prod. -func GetProfile() (*Profile, error) { - profile := Profile{} - err := viper.Unmarshal(&profile) - if err != nil { - return nil, err +func (p *Profile) Validate() error { + if p.Mode != "demo" && p.Mode != "dev" && p.Mode != "prod" { + p.Mode = "demo" } - if profile.Mode != "demo" && profile.Mode != "dev" && profile.Mode != "prod" { - profile.Mode = "demo" - } - - if profile.Mode == "prod" && profile.Data == "" { + if p.Mode == "prod" && p.Data == "" { if runtime.GOOS == "windows" { - profile.Data = filepath.Join(os.Getenv("ProgramData"), "memos") - - if _, err := os.Stat(profile.Data); os.IsNotExist(err) { - if err := os.MkdirAll(profile.Data, 0770); err != nil { - fmt.Printf("Failed to create data directory: %s, err: %+v\n", profile.Data, err) - return nil, err + p.Data = filepath.Join(os.Getenv("ProgramData"), "memos") + if _, err := os.Stat(p.Data); os.IsNotExist(err) { + if err := os.MkdirAll(p.Data, 0770); err != nil { + fmt.Printf("Failed to create data directory: %s, err: %+v\n", p.Data, err) + return err } } } else { - profile.Data = "/var/opt/memos" + p.Data = "/var/opt/memos" } } - dataDir, err := checkDataDir(profile.Data) + dataDir, err := checkDataDir(p.Data) if err != nil { fmt.Printf("Failed to check dsn: %s, err: %+v\n", dataDir, err) - return nil, err + return err } - profile.Data = dataDir - if profile.Driver == "sqlite" && profile.DSN == "" { - dbFile := fmt.Sprintf("memos_%s.db", profile.Mode) - profile.DSN = filepath.Join(dataDir, dbFile) + p.Data = dataDir + if p.Driver == "sqlite" && p.DSN == "" { + dbFile := fmt.Sprintf("memos_%s.db", p.Mode) + p.DSN = filepath.Join(dataDir, dbFile) } - profile.Version = version.GetCurrentVersion(profile.Mode) - return &profile, nil + return nil } diff --git a/server/router/api/v1/auth_service.go b/server/router/api/v1/auth_service.go index 0a41aa2e..b2e63222 100644 --- a/server/router/api/v1/auth_service.go +++ b/server/router/api/v1/auth_service.go @@ -224,7 +224,7 @@ func (s *APIV1Service) SignOut(ctx context.Context, _ *v1pb.SignOutRequest) (*em Name: fmt.Sprintf("%s%d", UserNamePrefix, user.ID), AccessToken: accessToken, }); err != nil { - slog.Error("failed to delete access token", slog.Any("err", err)) + slog.Error("failed to delete access token", "error", err) } } } diff --git a/server/router/api/v1/workspace_service.go b/server/router/api/v1/workspace_service.go index 2cbc67fb..1c794691 100644 --- a/server/router/api/v1/workspace_service.go +++ b/server/router/api/v1/workspace_service.go @@ -13,9 +13,10 @@ import ( func (s *APIV1Service) GetWorkspaceProfile(ctx context.Context, _ *v1pb.GetWorkspaceProfileRequest) (*v1pb.WorkspaceProfile, error) { workspaceProfile := &v1pb.WorkspaceProfile{ - Version: s.Profile.Version, - Mode: s.Profile.Mode, - Public: s.Profile.Public, + Version: s.Profile.Version, + Mode: s.Profile.Mode, + Public: s.Profile.Public, + PasswordAuth: s.Profile.PasswordAuth, } owner, err := s.GetInstanceOwner(ctx) if err != nil { @@ -24,8 +25,9 @@ func (s *APIV1Service) GetWorkspaceProfile(ctx context.Context, _ *v1pb.GetWorks if owner != nil { workspaceProfile.Owner = owner.Name } else { - // If owner is not found, set public to true. + // If owner is not found, set Public/PasswordAuth to true. workspaceProfile.Public = true + workspaceProfile.PasswordAuth = true } return workspaceProfile, nil } diff --git a/server/server.go b/server/server.go index 0b544c4c..cf5854bb 100644 --- a/server/server.go +++ b/server/server.go @@ -102,19 +102,19 @@ func (s *Server) Start(ctx context.Context) error { go func() { grpcListener := muxServer.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) if err := s.grpcServer.Serve(grpcListener); err != nil { - slog.Error("failed to serve gRPC", err) + slog.Error("failed to serve gRPC", "error", err) } }() go func() { httpListener := muxServer.Match(cmux.HTTP1Fast(http.MethodPatch)) s.echoServer.Listener = httpListener if err := s.echoServer.Start(address); err != nil { - slog.Error("failed to start echo server", err) + slog.Error("failed to start echo server", "error", err) } }() go func() { if err := muxServer.Serve(); err != nil { - slog.Error("mux server listen error", err) + slog.Error("mux server listen error", "error", err) } }() s.StartBackgroundRunners(ctx) diff --git a/server/service/s3_object_presigner/s3_object_presigner.go b/server/service/s3_object_presigner/s3_object_presigner.go index 29164bd8..f4873ee0 100644 --- a/server/service/s3_object_presigner/s3_object_presigner.go +++ b/server/service/s3_object_presigner/s3_object_presigner.go @@ -63,7 +63,7 @@ func (p *S3ObjectPresigner) CheckAndPresign(ctx context.Context) { s3Client, err := s3.NewClient(ctx, s3Config) if err != nil { - slog.Error("Failed to create S3 client", slog.Any("err", err)) + slog.Error("Failed to create S3 client", "error", err) continue } diff --git a/store/db/mysql/mysql.go b/store/db/mysql/mysql.go index 94365d7e..d8c6eccc 100644 --- a/store/db/mysql/mysql.go +++ b/store/db/mysql/mysql.go @@ -52,7 +52,7 @@ func (d *DB) GetCurrentDBSize(ctx context.Context) (int64, error) { " GROUP BY `table_schema`" rows, err := d.db.QueryContext(ctx, query, d.config.DBName) if err != nil { - slog.Error("Query db size error, make sure you have enough privilege", err) + slog.Error("Query db size error, make sure you have enough privilege", "error", err) return 0, err } defer rows.Close() diff --git a/web/src/pages/SignIn.tsx b/web/src/pages/SignIn.tsx index 83c20f75..fe18e916 100644 --- a/web/src/pages/SignIn.tsx +++ b/web/src/pages/SignIn.tsx @@ -116,57 +116,61 @@ const SignIn = () => { {workspaceGeneralSetting.customProfile?.title || "Memos"}

-
-
-
- {t("common.username")} - +
+
+ {t("common.username")} + +
+
+ {t("common.password")} + +
+
+
+ setRemember(e.target.checked)} />
-
- {t("common.password")} - +
-
-
- setRemember(e.target.checked)} - /> -
-
- -
- - {commonContext.profile.public && ( + + ) : ( +

Password auth is not allowed.

+ )} + {commonContext.profile.public && commonContext.profile.passwordAuth && (

{t("auth.sign-up-tip")} diff --git a/web/src/pages/SignUp.tsx b/web/src/pages/SignUp.tsx index 2bdf75bd..a3341a2c 100644 --- a/web/src/pages/SignUp.tsx +++ b/web/src/pages/SignUp.tsx @@ -1,6 +1,6 @@ import { Button, Input } from "@mui/joy"; import { ClientError } from "nice-grpc-web"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import { toast } from "react-hot-toast"; import { Link } from "react-router-dom"; import AppearanceSelect from "@/components/AppearanceSelect"; @@ -26,12 +26,6 @@ const SignUp = () => { const workspaceGeneralSetting = workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.GENERAL).generalSetting || WorkspaceGeneralSetting.fromPartial({}); - useEffect(() => { - if (!commonContext.profile.public) { - toast.error("Sign up is not allowed."); - } - }, []); - const handleUsernameInputChanged = (e: React.ChangeEvent) => { const text = e.target.value as string; setUsername(text); @@ -85,49 +79,55 @@ const SignUp = () => { {workspaceGeneralSetting.customProfile?.title || "Memos"}

-

{t("auth.create-your-account")}

-
-
-
- {t("common.username")} - -
-
- {t("common.password")} - -
-
-
- -
-
+ {commonContext.profile.public ? ( + <> +

{t("auth.create-your-account")}

+
+
+
+ {t("common.username")} + +
+
+ {t("common.password")} + +
+
+
+ +
+
+ + ) : ( +

Sign up is not allowed.

+ )} {!commonContext.profile.owner ? (

{t("auth.host-tip")}

) : (