From 52539fc130f0f7a0ca7af93b3df5a7fb5bd011b3 Mon Sep 17 00:00:00 2001 From: Lincoln Nogueira Date: Wed, 31 Jan 2024 02:16:31 -0300 Subject: [PATCH] chore: prevent visitors from breaking demo (#2869) * chore: add en-GB language * chore: remove en-GB contents * chore: prevent visitors from breaking demo - prevent disabling password login - prevent updating `memos-demo` user - prevent setting additional style - prevent setting additional script - add some error feedback to system settings UI * Revert "chore: add en-GB language" This reverts commit 2716377b04ca684abd03f76c1661000fd6994be8. --- api/v1/system_setting.go | 10 ++++++++++ api/v1/user.go | 12 ++++++++++++ api/v2/user_service.go | 8 ++++++++ api/v2/workspace_service.go | 9 +++++++++ web/src/components/Settings/SystemSection.tsx | 6 ++++-- 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/api/v1/system_setting.go b/api/v1/system_setting.go index 7cb79f12..c78a92d9 100644 --- a/api/v1/system_setting.go +++ b/api/v1/system_setting.go @@ -159,6 +159,16 @@ func (s *APIV1Service) CreateSystemSetting(c echo.Context) error { if err := systemSettingUpsert.Validate(); err != nil { return echo.NewHTTPError(http.StatusBadRequest, "invalid system setting").SetInternal(err) } + if s.Profile.Mode == "demo" { + switch systemSettingUpsert.Name { + case SystemSettingAdditionalStyleName: + return echo.NewHTTPError(http.StatusForbidden, "additional style is not allowed in demo mode") + case SystemSettingAdditionalScriptName: + return echo.NewHTTPError(http.StatusForbidden, "additional script is not allowed in demo mode") + case SystemSettingDisablePasswordLoginName: + return echo.NewHTTPError(http.StatusForbidden, "disabling password login is not allowed in demo mode") + } + } if systemSettingUpsert.Name == SystemSettingDisablePasswordLoginName { var disablePasswordLogin bool if err := json.Unmarshal([]byte(systemSettingUpsert.Value), &disablePasswordLogin); err != nil { diff --git a/api/v1/user.go b/api/v1/user.go index db995efe..4dc5be15 100644 --- a/api/v1/user.go +++ b/api/v1/user.go @@ -316,6 +316,14 @@ func (s *APIV1Service) DeleteUser(c echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, "Cannot delete current user") } + findUser, err := s.Store.GetUser(ctx, &store.FindUser{ID: &userID}) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err) + } + if s.Profile.Mode == "demo" && findUser.Username == "memos-demo" { + return echo.NewHTTPError(http.StatusForbidden, "Unauthorized to delete this user in demo mode") + } + if err := s.Store.DeleteUser(ctx, &store.DeleteUser{ ID: userID, }); err != nil { @@ -366,6 +374,10 @@ func (s *APIV1Service) UpdateUser(c echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, "Invalid update user request").SetInternal(err) } + if s.Profile.Mode == "demo" && *request.Username == "memos-demo" { + return echo.NewHTTPError(http.StatusForbidden, "Unauthorized to update user in demo mode") + } + currentTs := time.Now().Unix() userUpdate := &store.UpdateUser{ ID: userID, diff --git a/api/v2/user_service.go b/api/v2/user_service.go index 0d7faeb2..afffb78a 100644 --- a/api/v2/user_service.go +++ b/api/v2/user_service.go @@ -130,6 +130,10 @@ func (s *APIV2Service) UpdateUser(ctx context.Context, request *apiv2pb.UpdateUs return nil, status.Errorf(codes.NotFound, "user not found") } + if s.Profile.Mode == "demo" && user.Username == "memos-demo" { + return nil, status.Errorf(codes.PermissionDenied, "unauthorized to update user in demo mode") + } + currentTs := time.Now().Unix() update := &store.UpdateUser{ ID: user.ID, @@ -197,6 +201,10 @@ func (s *APIV2Service) DeleteUser(ctx context.Context, request *apiv2pb.DeleteUs return nil, status.Errorf(codes.NotFound, "user not found") } + if s.Profile.Mode == "demo" && user.Username == "memos-demo" { + return nil, status.Errorf(codes.PermissionDenied, "unauthorized to delete this user in demo mode") + } + if err := s.Store.DeleteUser(ctx, &store.DeleteUser{ ID: user.ID, }); err != nil { diff --git a/api/v2/workspace_service.go b/api/v2/workspace_service.go index 112061d3..6e34d58b 100644 --- a/api/v2/workspace_service.go +++ b/api/v2/workspace_service.go @@ -45,6 +45,9 @@ func (s *APIV2Service) UpdateWorkspaceProfile(ctx context.Context, request *apiv return nil, status.Errorf(codes.Internal, "failed to update allow_registration system setting: %v", err) } } else if field == "disable_password_login" { + if s.Profile.Mode == "demo" { + return nil, status.Errorf(codes.PermissionDenied, "disabling password login is not allowed in demo mode") + } _, err := s.Store.UpsertWorkspaceSetting(ctx, &store.WorkspaceSetting{ Name: "disable-password-login", Value: strconv.FormatBool(request.WorkspaceProfile.DisablePasswordLogin), @@ -53,6 +56,9 @@ func (s *APIV2Service) UpdateWorkspaceProfile(ctx context.Context, request *apiv return nil, status.Errorf(codes.Internal, "failed to update disable_password_login system setting: %v", err) } } else if field == "additional_script" { + if s.Profile.Mode == "demo" { + return nil, status.Errorf(codes.PermissionDenied, "additional script is not allowed in demo mode") + } _, err := s.Store.UpsertWorkspaceSetting(ctx, &store.WorkspaceSetting{ Name: "additional-script", Value: request.WorkspaceProfile.AdditionalScript, @@ -61,6 +67,9 @@ func (s *APIV2Service) UpdateWorkspaceProfile(ctx context.Context, request *apiv return nil, status.Errorf(codes.Internal, "failed to update additional_script system setting: %v", err) } } else if field == "additional_style" { + if s.Profile.Mode == "demo" { + return nil, status.Errorf(codes.PermissionDenied, "additional style is not allowed in demo mode") + } _, err := s.Store.UpsertWorkspaceSetting(ctx, &store.WorkspaceSetting{ Name: "additional-style", Value: request.WorkspaceProfile.AdditionalStyle, diff --git a/web/src/components/Settings/SystemSection.tsx b/web/src/components/Settings/SystemSection.tsx index 4a783f6e..f051d471 100644 --- a/web/src/components/Settings/SystemSection.tsx +++ b/web/src/components/Settings/SystemSection.tsx @@ -152,7 +152,8 @@ const SystemSection = () => { name: "additional-style", value: JSON.stringify(state.additionalStyle), }); - } catch (error) { + } catch (error: any) { + toast.error(error.response.data.message); console.error(error); return; } @@ -172,7 +173,8 @@ const SystemSection = () => { name: "additional-script", value: JSON.stringify(state.additionalScript), }); - } catch (error) { + } catch (error: any) { + toast.error(error.response.data.message); console.error(error); return; }