Skip to content

Lock system-wide settings in store panel & add "All stores" scope in admin#724

Merged
KrzysztofPajak merged 1 commit into
developfrom
store-system-settings-scope
Jul 5, 2026
Merged

Lock system-wide settings in store panel & add "All stores" scope in admin#724
KrzysztofPajak merged 1 commit into
developfrom
store-system-settings-scope

Conversation

@KrzysztofPajak

@KrzysztofPajak KrzysztofPajak commented Jul 5, 2026

Copy link
Copy Markdown
Member

Summary

Follow-up to the store-owner panel security review: some setting fields have cross-store / system impact and must stay under administrator control, plus the admin panel gets a proper way to manage the global settings record.

Store panel (Grand.Web.Store)

Store owners can no longer change:

  • CustomerSettings.DefaultPasswordFormat and HashedPasswordFormat - password storage is a system-wide concern; a per-store downgrade would affect shared customer accounts,
  • LoyaltyPointsSettings.PointsAccumulatedForAllStores - a store owner enabling cross-store accumulation (combined with inflated earning rates in his own store) could mint points redeemable in other stores.

The inputs are removed from the store views and the values are preserved server-side on save (snapshot from the store-scoped load before ToEntity, restored after), following the same pattern already used for the media file-manager fields.

Admin panel (Grand.Web.Admin)

  • The store scope selector now includes an "All stores" option (uses the existing Admin.Settings.StoreScope.AllStores resource). Selecting it loads/saves the global settings record, which stores without their own record inherit automatically - so the administrator no longer has to re-apply settings for every newly created store.
  • BaseAdminController.GetActiveStore() returns the global scope ("") when no store is selected or the selected store no longer exists, instead of silently falling back to the first store. This aligns it with AdminStoreService.GetActiveStore() and with what the selector displays.
  • Removed dead IsStoreManager branches in StoreScopeViewComponent and BaseAdminController - store managers have no access to the admin panel.

Behavior note

On multi-store installations where the administrator never picked a store scope, settings pages previously edited the first store; they now edit the global scope until a store is selected.

Test plan

  • Grand.Web.Store and Grand.Web.Admin build clean (0 warnings / 0 errors)
  • Tests touching GetActiveStore (PaymentController, AdminStoreService) pass
  • Manual: multi-store admin - select "All stores", save Customer/Sales settings, verify a store without its own record inherits them
  • Manual: store owner panel - verify password format / points accumulation fields are gone and saving a tab keeps admin-managed values intact

🤖 Generated with Claude Code

…admin

Store panel (Grand.Web.Store):
- Store owners can no longer change password storage formats
  (CustomerSettings.DefaultPasswordFormat, HashedPasswordFormat) and
  LoyaltyPointsSettings.PointsAccumulatedForAllStores - the values are
  preserved server-side on save and the inputs are removed from the views.
  These are administrator-managed settings; a store owner able to enable
  cross-store points accumulation or downgrade password hashing would
  impact other stores.

Admin panel (Grand.Web.Admin):
- Store scope selector now offers an "All stores" option so the
  administrator can manage the global settings record directly; new
  stores inherit it automatically instead of requiring per-store updates.
- GetActiveStore() returns the global scope ("") when no store is
  selected instead of falling back to the first store.
- Removed dead IsStoreManager branches - store managers have no access
  to the admin panel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 5, 2026 08:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens multi-store settings governance by preventing store owners from editing system-wide sensitive settings in the store panel, and adds an “All stores” (global scope) option to the admin store-scope selector so administrators can manage the global settings record used as the default for stores without overrides.

Changes:

  • Store panel: remove UI for cross-store loyalty point accumulation and password format fields; preserve those values server-side on save to prevent tampering.
  • Admin panel: add an “All stores” scope option and adjust active-store resolution to use the global scope ("") when no/invalid store is selected.
  • Admin cleanup: remove store-manager-only branches from admin store scope logic.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Web/Grand.Web.Store/Controllers/SettingController.cs Preserves administrator-controlled fields during store-owner saves (Sales + Customer settings).
src/Web/Grand.Web.Store/Areas/Store/Views/Setting/Partials/Sales.TabLoyaltyPoints.cshtml Removes the cross-store accumulation toggle from the store-owner UI.
src/Web/Grand.Web.Store/Areas/Store/Views/Setting/Partials/Customer.TabCustomerSecurity.cshtml Removes password format selectors from the store-owner UI.
src/Web/Grand.Web.Admin/Controllers/BaseAdminController.cs Changes default/invalid admin store scope handling to return the global scope ("").
src/Web/Grand.Web.Admin/Components/StoreScope.cs Adds an “All stores” option to the admin store scope dropdown.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Web/Grand.Web.Admin/Controllers/BaseAdminController.cs
@KrzysztofPajak KrzysztofPajak merged commit 6631acb into develop Jul 5, 2026
6 of 8 checks passed
@KrzysztofPajak KrzysztofPajak deleted the store-system-settings-scope branch July 5, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants